diff --git a/README.md b/README.md index 6aff6f6..1784397 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,106 @@ -# server-flask -# git-commit-message-convention - -| Type | Description | -|:-------------:|-------------| -| `feat` | 기능 개발 시 | -| `bug` | 버그 발생 시 | -| `chore` | 전반적인 환경 설정 시 | -| `docs` | 문서 작업 시 | -| `fix` | 기존 작성된 코드 수정 시 | -| `refactor` | 리펙토링 시 | -| `test` | 테스트 관련 | +![header](https://capsule-render.vercel.app/api?type=waving&color=BF92FB&height=300§ion=header&text=capic&fontSize=50&fontColor=FFF&fontAlignY=40&desc=영상%20자동%20모자이크%20서비스&descAlign=80) +
+ +## 작품 개요 +capic은 영상에 등장하는 얼굴을 추출하여 선별하고, 자동으로 모자이크 처리된 동영상을 만들어주는 서비스입니다.
+사용자들은 더욱 자유롭게 자신들의 영상을 공유할 수 있는 환경이 마련되어 다채로운 콘텐츠를 만드는 데에 기여합니다.

+시연영상 보러가기
+영상 용량에 의해 미리보기가 제공되지 않습니다. 다운로드 후 시청 부탁드립니다. + +

+ +## 기대 효과 +* 자유로운 비디오 공유: 개인이 자신의 비디오를 더 자유롭게 공유할 수 있게 되어,
+공공장소에서의 촬영 부담이 줄어든다. 이로 인해 사용자는 더 창의적이고 다양한 콘텐츠를 만들 수 있는 환경이 조성된다.

+ +* 프라이버시 보호와 사회적 이익 증진: 광고, 교육, 의료, 보안 등 다양한 분야에서 개인의 프라이버시를 보호하고,
+이를 통해 사회적 이익을 증진시킬 수 있다.

+ +* 효율적인 비디오 관리: 저희 서비스는 '블러미'와 같은 유사 서비스와 비교하여 더욱 발전된 기능을 제공한다.
+영상에서 자주 노출되는 얼굴을 자동으로 식별하고, 사용자가 원하지 않는 얼굴만 선택적으로 블러 처리할 수 있어
+ 사용자의 필요에 따라 안전하고 맞춤화된 경험을 제공할 수 있다. +

+ +## 팀원 + + + + + + + + + + + + + + +
김유나이서연이세은이지연
+

+ +## 작품 설명 +### 1)시작페이지 +

+ + +

+ +* 사용자가 모자이크 처리를 원하는 동영상을 선택합니다.
+ +### 2)얼굴추출 +

+ + +

+ +* 영상에 나오는 인물들 얼굴을 추출하여 보여줍니다. +* 사용자가 모자이크 처리 제외할 얼굴을 선택합니다. +* 영상에 나오는 빈도에 따라 많이 나온 순서대로 추천합니다. +* 선택이 완료되면, 모자이크 처리되는 동안 로딩 페이지를 보여줍니다.

+* 구현 방법
+ 동영상을 프레임 단위로 사람들의 얼굴을 추출하였습니다.
OpenCV로 각 프레임을 읽고, insightface 라이브러리를 이용해 얼굴들 위치를 탐지하여 특징에 따라 각 얼굴 인코딩을 생성합니다.
Numpy를 이용해 인코딩 간의 거리 계산법을 사용하여 유사도에 따라 인물 별로 식별합니다.
최종적으로 슬라이더에 추출된 얼굴의 빈도수에 따라 순서대로 보여집니다.
+ +### 3)모자이크 +

+ +

+ +* 변환된 영상 미리보기를 제공합니다. +* 변환된 영상을 사용자가 다운로드 받을 수 있습니다.

+* 구현 방법
+ 객체 탐지 모델인 yolov5 모델을 사람의 얼굴만 탐지를 할 수 있도록 wider-face dataset을 이용해서 학습시켰습니다.
+ 모자이크 처리 시에 특정 사람의 얼굴만 제외하기 위해 deepface 라이브러리의 facenet 모델을 사용하였고
소요 시간을 줄이기 위해서 라이브러리를 튜닝하였습니다. + +

+ +## 아키텍처 +

+ +

+

+ +## 서비스 구조 +

+ +

+

+ +## 주요기술 +* 개발 언어
+![HTML5](https://img.shields.io/badge/html5-%23E34F26.svg?style=for-the-badge&logo=html5&logoColor=white) +![CSS3](https://img.shields.io/badge/css3-%231572B6.svg?style=for-the-badge&logo=css3&logoColor=white) +![JavaScript](https://img.shields.io/badge/javascript-%23323330.svg?style=for-the-badge&logo=javascript&logoColor=%23F7DF1E) +![Python](https://img.shields.io/badge/Python-3776AB.svg?style=for-the-badge&logo=Python&logoColor=white) +![Java17](https://img.shields.io/badge/java-%23ED8B00.svg?style=for-the-badge&logo=JAVA&logoColor=white) + +* 사용 기술
+![OpenCV](https://img.shields.io/badge/OpenCV-5C3EE8.svg?style=for-the-badge&logo=OpenCV&logoColor=white) +![Insightface](https://img.shields.io/badge/Insightface-FF6F61.svg?style=for-the-badge) +![YOLOv5](https://img.shields.io/badge/YOLOv5-00FFFF.svg?style=for-the-badge) +![DeepFace](https://img.shields.io/badge/DeepFace-FFD700.svg?style=for-the-badge) +![Spring Boot](https://img.shields.io/badge/Spring%20Boot-6DB33F.svg?style=for-the-badge&logo=Spring-Boot&logoColor=white) +![Flask](https://img.shields.io/badge/Flask-000000.svg?style=for-the-badge&logo=Flask&logoColor=white) +![Amazon S3](https://img.shields.io/badge/Amazon%20S3-569A31.svg?style=for-the-badge&logo=Amazon-S3&logoColor=white) + +![footer](https://capsule-render.vercel.app/api?section=footer&type=waving&color=BF92FB&height=300) diff --git a/__pycache__/mosaic.cpython-311.pyc b/__pycache__/mosaic.cpython-311.pyc index e08a78b..020de69 100644 Binary files a/__pycache__/mosaic.cpython-311.pyc and b/__pycache__/mosaic.cpython-311.pyc differ diff --git a/mosaic.py b/mosaic.py index 87df73e..ef6fd1a 100644 --- a/mosaic.py +++ b/mosaic.py @@ -36,6 +36,9 @@ def mosaic(video_path, image_paths): ) embedding_list.append(embedding_result["embeddings"][0]) + threshold = 0.3 + not_threshold = 0.47 + while cap.isOpened(): ret, frame = cap.read() if not ret: @@ -46,13 +49,6 @@ def mosaic(video_path, image_paths): print(f"{current_frame_count}감지 시작") - if len(detections.xyxy[0]) > 2: - threshold = 0.27 - not_threshold = 0.2851 - else: - threshold = 0.3 - not_threshold = 0.47 - for face_id in detections.xyxy[0]: x1, y1, x2, y2 = face_id[:4].int().tolist() if y2 - y1 > 50 and x2 - x1 > 50: @@ -84,9 +80,15 @@ def mosaic(video_path, image_paths): break if distance > not_threshold: + face_filename = f"D/face_{face_count}.jpg" + verified_str = 'Different' + distance_str = '(%.4f >= %.4f)' % (distance, threshold) + print(face_filename, verified_str, distance_str) face = cv2.resize(face_image, (10, 10)) face = cv2.resize(face, (x2 - x1, y2 - y1), interpolation=cv2.INTER_AREA) frame[y1:y2, x1:x2] = face + face_filepath = os.path.join(faces_dir, face_filename) + cv2.imwrite(face_filepath, face_image) break face_count += 1