Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ljy67122 #19

Merged
merged 7 commits into from
May 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,9 @@ wider face.v3i.yolov5pytorch
dist
build
myenv
__pycache__
DroneFace
pytorch/deep_sort
pytorch/wider face.v3i.yolov5pytorch
pytorch/yolov5
pytorch/deep_sort
*.mp4
Binary file added __pycache__/createTarget.cpython-310.pyc
Binary file not shown.
Binary file added __pycache__/deep2.cpython-310.pyc
Binary file not shown.
Binary file added __pycache__/mosaic.cpython-310.pyc
Binary file not shown.
Binary file added __pycache__/mosaic_jiyeon.cpython-310.pyc
Binary file not shown.
Binary file added __pycache__/yoona_target.cpython-310.pyc
Binary file not shown.
Binary file removed __pycache__/yoona_target.cpython-311.pyc
Binary file not shown.
14 changes: 9 additions & 5 deletions app.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import os
from createTarget import extract_and_identify_faces_from_video
from yoona_target import yoona_test
import mosaic
from yoona_target import arcface_recognition, group_and_save_faces
# import mosaic
import mosaic_jiyeon
# import deep2


from flask import (Flask, request, send_file, jsonify)
Expand All @@ -24,7 +26,8 @@ def process_video():
@app.route('/target2', methods=['POST'])
def yoona():
video_path='./cutVideo.mp4'
identified_faces = yoona_test(video_path)
identified_faces = arcface_recognition(video_path)
base64_faces = group_and_save_faces(identified_faces)
# face_base64_arrays = save_faces(identified_faces) # 이미지를 Base64 인코딩된 문자열로 반환
return jsonify({"images": identified_faces}) # JSON 객체로 변환

Expand All @@ -47,8 +50,9 @@ def handle_video():
image_paths.append(image_filename)
print(f'Image {i} saved successfully.')

output_video_path = mosaic.mosaic(video_file.filename, image_paths)
# output_video_path = mosaic_jiyeon.mosaic(video_file.filename, image_paths)
# output_video_path = mosaic.mosaic(video_file.filename, image_paths)
output_video_path = mosaic_jiyeon.mosaic(video_file.filename, image_paths)
# output_video_path = deep2.mosaic(video_file.filename, image_paths)
print(output_video_path)
return send_file(output_video_path, mimetype='video/mp4', as_attachment=True, download_name='output_video.mp4')

Expand Down
Binary file added best.pt
Binary file not shown.
Binary file added cutVideo2.mp4
Binary file not shown.
114 changes: 114 additions & 0 deletions deep.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import cv2
import torch
import os
import time
from deepface import DeepFace
import os
import tensorflow as tf
from tensorflow import keras
from tensorflow.python.client import device_lib
import gc

def mosaic(video_path, image_paths):
# os.environ["CUDA_VISIBLE_DEVICES"] = "0"
# print("deepdepp")
# print(device_lib.list_local_devices())
gc.collect()
torch.cuda.empty_cache()
print(tf.test.is_gpu_available())

start_time = time.time() # 시작 시간 기록
# YOLOv5 모델 로드
model = torch.hub.load('pytorch/yolov5', 'custom', path='./best.pt', source='local') # 모델 로드
# device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') # 디바이스 설정
# torch.cuda.empty_cache()
# model.to(device)

output_video_path = os.path.join('pytorch/tmp', video_path)

# 모자이크 처리할 사이즈 정의
block_size = 10

# 동영상 파일 열기
cap = cv2.VideoCapture(video_path)

# 결과 동영상 파일 생성
fps = int(cap.get(cv2.CAP_PROP_FPS))
frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
out = cv2.VideoWriter(output_video_path, cv2.VideoWriter.fourcc(*'mp4v'), fps, (frame_width, frame_height))

embedding_list = []
for image_path in image_paths:
embedding_result = DeepFace.create_verification_result(
img1_path=image_path,
detector_backend='retinaface',
model_name='Facenet',
enforce_detection=False
)
embedding_list.append(embedding_result["embeddings"][0])

# 동영상 프레임마다 처리
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break

# YOLOv5를 사용하여 객체 감지
results = model(frame)

threshold = 0.465

# 감지된 얼굴에 모자이크 처리
for result in results.xyxy[0]:
if result[5] == 0: # 클래스 인덱스가 0일 때(사람 얼굴을 의미하는 클래스)
x1, y1, x2, y2 = result[:4].int().tolist()

# 얼굴 영역 추출
face_roi = frame[y1:y2, x1:x2]

# 얼굴 이미지 크기 조정
face_roi_resized = cv2.resize(face_roi, (224, 224))
cv2.imwrite("pytorch/output_image.jpeg", face_roi_resized)

# 특정 사람과의 얼굴 일치 여부 확인
match = False
for ref_face in embedding_list:
image = cv2.imread(image_path)
similarity = DeepFace.verify(img1_path= face_roi_resized, img2_path= ref_face, model_name ='Facenet512', enforce_detection=False)
if similarity["verified"] and similarity['distance'] < threshold: # 유사성이 임계값보다 크면 얼굴이 일치한다고 판단
match = True
break
# os.remove("output_image.jpg")

if match: # 특정 사람과 일치하지 않는 경우에만 모자이크 처리
# 얼굴 영역에 모자이크 처리
continue

blurred_face = cv2.resize(face_roi, (block_size, block_size))
blurred_face = cv2.resize(blurred_face, (x2 - x1, y2 - y1), interpolation=cv2.INTER_AREA)
frame[y1:y2, x1:x2] = blurred_face

# 모자이크 처리된 프레임 결과 동영상에 추가
out.write(frame)

# 작업 완료 후 파일 닫기
cap.release()
out.release()
cv2.destroyAllWindows()

end_time = time.time() # 종료 시간 기록
elapsed_time = end_time - start_time # 소요된 시간 계산
print(f"걸린 시간: {elapsed_time} 초")

return output_video_path

if __name__ == "__main__":
import sys
video_path = sys.argv[1]
image_paths = ["save/train/Gongyoo/1.jpeg","save/train/Gongyoo/2.jpeg","save/train/Gongyoo/3.jpeg","save/train/Gongyoo/4.jpeg","save/train/Gongyoo/5.jpeg","save/train/Gongyoo/6.jpeg"]
mosaic(video_path, image_paths)
# import os
#
# os.environ['CUDA_VISIBLE_DEVICES'] = '0'
# print("GPU 사용 가능 여부:", tf.test.is_gpu_available())
103 changes: 103 additions & 0 deletions deep2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import cv2
import os
from deepface import DeepFace
import torch


def mosaic(video_path, image_paths):
model_name = "Facenet512"

output_video_path = os.path.join('tmp', 'output.mp4')
cap = cv2.VideoCapture(video_path)
fps = int(cap.get(cv2.CAP_PROP_FPS))
frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
out = cv2.VideoWriter(output_video_path, cv2.VideoWriter.fourcc(*'mp4v'), fps, (frame_width, frame_height))
total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) # 동영상의 전체 프레임 수를 얻음

print(f"Total number of frames in the video: {total_frames}")
block_size = 10

threshold = 0.465
not_threshold = 0.55

faces_dir = os.path.join('tmp', 'faces')
if not os.path.exists(faces_dir):
os.makedirs(faces_dir)

face_count = 0
current_frame_count = 0

# model = torch.hub.load('./yolov5', 'custom', path='macWideface.pt', force_reload=True, source='local')
model = torch.hub.load('./yolov5', 'custom', path='best.pt', force_reload=True, source='local')

embedding_list = []
for image_path in image_paths:
embedding_result = DeepFace.create_verification_result(
img1_path=image_path,
detector_backend='retinaface',
model_name=model_name,
enforce_detection=False
)
embedding_list.append(embedding_result["embeddings"][0])

while cap.isOpened():
ret, frame = cap.read()
if not ret:
break

# detections = RetinaFace.detect_faces(img_path=frame)
detections = model(frame)

print(f"{current_frame_count}감지 시작")

for result in detections.xyxy[0]:
if result[5] == 0: # 클래스 인덱스가 0일 때(사람 얼굴을 의미하는 클래스)
x1, y1, x2, y2 = result[:4].int().tolist()

# 얼굴 영역 추출
face_roi = frame[y1:y2, x1:x2]

# 특정 사람과의 얼굴 일치 여부 확인
match = False
for ref_face in embedding_list:
similarity = DeepFace.verify(img1_path=face_roi, img2_path=ref_face,
model_name=model_name, enforce_detection=False)

if similarity["verified"] and not_threshold >= similarity['distance'] >= threshold:
face_filename = f"face_{face_count}.jpg"
verified_str = 'Different'
distance_str = '(%.4f <= %.4f)' % (similarity['distance'], threshold)
print(face_filename,verified_str, distance_str, similarity["verified"])
face_filepath = os.path.join(faces_dir, face_filename)
cv2.imwrite(face_filepath, face_roi)
face_count += 1

if similarity["verified"] and similarity['distance'] < threshold: # 유사성이 임계값보다 크면 얼굴이 일치한다고 판단
match = True
break
# os.remove("output_image.jpg")

if match: # 특정 사람과 일치하지 않는 경우에만 모자이크 처리
# 얼굴 영역에 모자이크 처리
continue

blurred_face = cv2.resize(face_roi, (block_size, block_size))
blurred_face = cv2.resize(blurred_face, (x2 - x1, y2 - y1), interpolation=cv2.INTER_AREA)
frame[y1:y2, x1:x2] = blurred_face

# 모자이크 처리된 프레임 결과 동영상에 추가
current_frame_count += 1
out.write(frame)

cap.release()
out.release()
cv2.destroyAllWindows()

return output_video_path

if __name__ == "__main__":
import sys
video_path = sys.argv[1]
image_paths = ["save/train/bbo/bbo.png","save/train/bbo/bbo2.png","save/train/bbo/bbo3.png","save/train/bbo/bbo4.png"]
mosaic(video_path, image_paths)
Binary file added dlib-19.22.99-cp310-cp310-win_amd64.whl
Binary file not shown.
43 changes: 43 additions & 0 deletions extract.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
from deepface import DeepFace
import cv2
import os
import numpy as np

# 이미지가 있는 디렉토리
directory_path = r'save/train/Gongyoo'

# 저장할 디렉토리 경로
save_directory = r'save/train/yoo'
if not os.path.exists(save_directory):
os.makedirs(save_directory)

# 디렉토리 내의 모든 이미지 파일을 순회
for filename in os.listdir(directory_path):
if filename.lower().endswith(('.png', '.jpg', '.jpeg')): # 이미지 파일 형식 확인
img_path = os.path.join(directory_path, filename).replace('\\', '/')
img = cv2.imread(img_path)

# RetinaFace로 얼굴 감지
try:
face = DeepFace.detectFace(img_path, detector_backend='retinaface', enforce_detection=False)

# 감지된 얼굴 이미지 저장
face_filename = os.path.join(save_directory, filename).replace('\\', '/')
if face is not None:
cv2.imshow("Original Face", face)
cv2.waitKey(0)
if face.dtype != np.uint8:
# 데이터 스케일링 및 타입 변환
face = np.clip(face * 255.0, 0, 255).astype(np.uint8)
# face = cv2.cvtColor(face, cv2.COLOR_RGB2BGR)

success = cv2.imwrite(face_filename, face)
if success:
print(f"{face_filename} 저장됨")
else:
print(f"{face_filename} 저장 실패")
else:
print(f"{filename}: 얼굴 감지 실패 또는 이미지 데이터 없음")

except Exception as e:
print(f"{filename} 처리 중 오류 발생: {str(e)}")
68 changes: 68 additions & 0 deletions face_yn.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import cv2
import face_recognition
import os
import numpy as np

def extract_and_identify_faces_from_video(video_path):
face_encodings = [] # 얼굴별 인코딩 저장
face_images = [] # 얼굴별 이미지 저장
identified_faces = [] # 식별된 얼굴별 (객체) 저장

video_capture = cv2.VideoCapture(video_path)

while video_capture.isOpened():
success, frame = video_capture.read()
if not success:
break

# face_locations = face_recognition.face_locations(frame) # 현재 프레임에서 얼굴 위치 탐지
face_locations = face_recognition.face_locations(frame, model='cnn')
current_encodings = face_recognition.face_encodings(frame, face_locations) # 얼굴 위치에 대한 인코딩

for (top, right, bottom, left), encoding in zip(face_locations, current_encodings):
# 얼굴 이미지 추출
face_image = frame[top:bottom, left:right]
face_images.append(face_image)
face_encodings.append(encoding)

# 인식된 얼굴 분류
for idx, encoding in enumerate(face_encodings):
if not identified_faces:
identified_faces.append([(face_images[idx], encoding)])
else:
matched = False
for face_group in identified_faces:
group_encodings = [enc for _, enc in face_group]
avg_encoding = np.mean(group_encodings, axis=0)
dist = np.linalg.norm(avg_encoding - encoding)
if dist < 0.56: # 같은 사람으로 판단하는 임계값
face_group.append((face_images[idx], encoding))
matched = True
break
if not matched:
identified_faces.append([(face_images[idx], encoding)])

video_capture.release()
return identified_faces # 객체별 리턴

def save_faces(identified_faces):
if not os.path.exists('saved_faces'): # 얼굴별 디렉토리 생성
os.makedirs('saved_faces')

for i, group in enumerate(identified_faces):
group_dir = f'saved_faces/group_{i}'
if not os.path.exists(group_dir):
os.makedirs(group_dir)
for j, (face, _) in enumerate(group[:3]): # 인물별 최대 3개까지 저장
cv2.imwrite(f'{group_dir}/face_{j}.jpg', face)

video_path = './video4.mp4' # 비디오 파일 삽입
identified_faces = extract_and_identify_faces_from_video(video_path) # identified_faces에 저장
save_faces(identified_faces) # 식별된 얼굴 저장

if identified_faces:
print(f"'saved_faces'에 저장 완료.")
else:
print("얼굴이미지없음.")


Loading