YOLO와 FaceNet 모델을

작품소개☆

이번 프로젝트에서는 FaceNet이라는 모델과 YOLO 모델을 적용했습니다.

1인 크리에이터와 SNS 인플루언서들이 사진이나 영상을 공개적으로 올리는 일이 늘고 있다.

다만, 사람이 많이 모이는 장소에서 사진이나 동영상을 촬영할 경우 일반인이 함께 촬영되는 경우가 있어 초상권이 보호되지 않을 수 있습니다.

이는 바람직하지 않게 보행자를 노출시킬 수 있으며,

작가 입장에서는 초상권 보호를 위해 영상 삭제를 요청하면 금전적인 피해를 입거나 사람의 얼굴을 직접 모자이크 처리해야 하는 불편함이 있을 수 있다고 느꼈습니다.

그래서 특정인에서 제외되고 싶지 않은 사람들을 자동으로 모자이크 처리할 수 있는 모델을 만들어 보았습니다.

https://drive.google.com/drive/folders/10BtvndKGUIEfBFq66WxDkwASNDcVvRGN?usp=share_link

인물 사진 보호 모자이크 처리 시스템 – Google 드라이브

이 폴더에는 파일이 없습니다.

이 폴더에 파일을 추가하려면 로그인하십시오.

drive.google.com


색인
1. 개발 환경
2번째 골
3. 나의 역할
4. 활동
5. 활동 결과
6. 종료

#3 YOLO와 FaceNet 모델로 인물 보호 모자이크 처리 모델 생성

근무기간 : 2022.09.23 ~ 2022.10.14 (약 3주)

1. 개발 환경

  • 사용 모델: YOLOv5s, YOLOv5m, YOLO7, FaceNet
  • 개발 언어: Python
  • 개발 도구: Google Colab, Jupyter Notebook, LabelImg

2번째 골

  • 원하는 얼굴 이미지를 학습하고 학습된 얼굴에서 다른 얼굴을 자동으로 모자이크 처리하는 모델을 구축합니다.

3. 나의 역할

  • 특정 개인 이미지 데이터 수집 및 라벨링 작업 수행(YOLO, FaceNet)
  • OpenCV를 이용한 모자이크 처리 코드 작성
  • FaceNet 모델의 구조 이해
  • YOLOv5s 및 YOLOv7 모델 구축 및 교육
  • FaceNet 모델 생성 및 학습
  • 모델별 테셀레이션 코드와 인식코드 결합

4. 활동

>> 특정인 이미지 데이터 수집 및 라벨링 작업 수행

YOLO 모델을 이용한 야생 동물 로드킬 방지 모델 구축

작품 소개 ☆ YOLOv5 모델로 구축된 최초의 인공지능 프로젝트. 최근 야생동물이 고속도로에 뛰어들어 사고가 난 한자 블랙박스 사고 영상을 봤습니다.

사고

my-portfolio-log.tistory.com

  • YOLO 모델과 달리 FaceNet에서 사용할 데이터는 단순하게 수집하지만 FaceNet을 위한 데이터 수집은 아래 FaceNet 모델의 구조 이해 섹션에서 설명합니다.

>> OpenCV를 이용한 모자이크 처리 코드 작성

  • OpenCV 라이브러리를 사용하여 모자이크 처리를 수행하는 코드를 작성했습니다.

  • 모자이크의 경우 이미지에서 원하는 영역을 추출할 수 있으며 추출된 부분을 의도적으로 깨뜨릴 수 있습니다.

import cv2

def blur_fun(frame, x, y, w, h) :
    try :
        face_img = frame(y:y+h, x:x+w) # 탐지된 얼굴 이미지 crop
        face_img = cv2.resize(face_img, dsize=(0, 0), fx=0.04, fy=0.04) # 축소
        face_img = cv2.resize(face_img, (w, h), interpolation=cv2.INTER_AREA) # 확대
        frame(y:y+h, x:x+w) = face_img # 탐지된 얼굴 영역 모자이크 처리
        return frame
    except :
        return frame
  • 나중에 이 함수를 모델을 인식하는 코드와 결합할 것입니다.

>> FaceNet 모델의 구조 이해

  • 간단히 설명하면 인물 이미지의 구체적인 특징을 찾아 그 특징을 바탕으로 새로운 이미지가 입력되면 다른 사람의 이미지와 그 사람의 이미지의 거리를 비교하여 더 가까운 이미지로 식별할 수 있는 모델이다.

  • k-최근접 이웃 기계 학습 모델처럼 느껴졌습니다.

  • 이 모델 학습 구조를 이해하려면 먼저 triplet loss를 이해하는 것이 중요합니다.

  • 삼쌍둥이 상실을 예로 설명하자면 어떤 사람(A)과 다른 사람(B) 사이에 어떤 사람(C)이 들어가고, A나 B와 더 비슷한 사람이 C에 가깝다고 생각할 수 있다.

    . 그리고 가까운 사람과 멀리 있는 사람의 거리를 계산하고 손실 함수를 만들어 그 차이가 얼마나 큰지를 계산하는 개념입니다.

  • FaceNet 모델에 대한 자세한 설명은 다음 링크를 참조하세요.
  • https://arxiv.org/abs/1503.03832

FaceNet: 얼굴 인식 및 클러스터링을 위한 통합 임베딩

최근 안면 인식 분야의 상당한 발전에도 불구하고 대규모 안면 확인 및 인식의 효율적인 구현은 현재 접근 방식에 심각한 문제를 제기합니다.

이 논문에서는 FaceNet이라는 시스템을 제시합니다.

archive.org

  • 모델을 검토한 후 특정 개인과 그렇지 않은 사람들에 대한 데이터 수집이 필요해 보였습니다.

  • 그리고 FaceNet 모델의 경우 적은 수의 이미지로도 이미지의 특징값을 얻을 수 있기 때문에 동일인 데이터와 타인 데이터를 각각 30파트 이내로 수집하였다.

>> YOLOv5s 및 YOLOv7 모델 구축 및 교육

울트라리틱스

더 쉽게. 더 똑똑해집니다.

더 나아가. Ultralytics에는 35개의 저장소가 있습니다.

GitHub에서 코드를 따르십시오.

github.com

GitHub – WongKinYiu/yolov7: Implementing Paper – YOLOv7: 훈련 가능한 공짜로 실시간을 한 단계 끌어올리다

종이의 구현 – YOLOv7: 훈련 가능한 공짜 주머니는 실시간 물체 탐지기를 위한 새로운 최첨단 기술을 설정합니다 – GitHub – WongKinYiu/yolov7: 종이의 구현 – YOLOv7: 훈련 가능한 주머니…

github.com

  • YOLOv5s 및 YOLOv5m 모델의 .yaml 파일을 수정하고 교육하는 프로세스는 이전 기사에 설명되어 있습니다.

  • YOLOv7은 YOLOv5와 유사합니다.

  • 먼저 Google 드라이브를 마운트하고 Git에서 yolo 7을 다운로드합니다.

# 구글 드라이브 연결
from google.colab import drive
drive.mount('/content/drive')

# /content 경로 이동
%cd /content/프로젝트 경로

# 깃에서 욜로 7 가져오기
!
git clone https://github.com/WongKinYiu/yolov7.git
  • 그리고 YOLOv5와 마찬가지로 data.yaml 및 yolo7.yaml 파일을 같은 방식으로 수정하고 훈련합니다.

  • 최고 : 여기서 여러 모델을 사용하는 이유는 최대한 많은 모델을 적용하고 성능이 더 좋은 모델을 선택하려고 노력했기 때문입니다.

    특히 모델이 무거울수록 GPU 리소스를 많이 소모하기 때문에 동일한 학습 조건을 설정할 수 없었습니다.

>> FaceNet 모델 구축 및 교육

GitHub – AISangam/Facenet-real-time-face-recognition-with-deep-learning-tensorflow: Facenet-real-time-face-recognition-with-de

Facenet real-time facial recognition with deep learning tensorflow – GitHub – AISangam/Facenet 실시간 얼굴 인식 with deep learning tensorflow: Facenet real-time facial recognition with dee…

github.com

  • 여기 Gitro 링크에서 설치할 수도 있습니다.

!
git clone https://github.com/AISangam/Facenet-Real-time-face-recognition-using-deep-learning-Tensorflow
  • 데이터 수집 시 특정인과 비특정인 데이터를 위한 새로운 폴더가 생성되어 새로운 폴더에 배치됩니다.

  • 그리고 data_preprocess.py 파일을 실행하여 이미지의 속성을 찾았습니다.

  • data_preprocess.py에 새로 생성된 폴더 이름이 train_img가 아닌 경우 새로 생성된 폴더 이름으로 변경합니다.

    (가능하면 영문 이름으로 폴더를 만들어 드립니다!
    )
!
python '절대 경로 지정'/data_preprocess.py
  • 이러한 특성 값으로 train_main.py를 실행하여 각 이미지를 학습시킵니다.

!
python '절대 경로 지정'/train_main.py
  • 지금까지 학습한 FaceNet 모델로 face_recognition.py 파일을 실행하면 얼굴을 찾는 것을 확인할 수 있습니다.

!
python '절대 경로 지정'/face_recognition.py
  • 전체적으로 FaceNet 모델을 사용하는 절차를 간략히 요약하면,
    1. 두 명 이상의 사람들로부터 이미지 데이터를 수집합니다.

    2. FaceNet 모델을 만듭니다.

    3. 새 폴더를 만들고 수집된 이미지를 그 안에 넣습니다.

    4. data_preprocess.py를 실행하여 이미지 기능을 찾습니다.

    5. 다음으로 train_main.py로 학습을 계속합니다.

    6. 학습이 끝나면 face_recognition.py 파일을 이용하여 인식을 시도할 수 있습니다.

>> 각 모델에 대한 모자이크 처리 코드와 탐지 코드 결합

  • 위에서 생성한 모자이크 처리 코드와 각 모델의 인식 코드를 결합합니다.

  • 첫 번째는 Yolo 모델입니다.

    yolo 모델의 경우 detect.py라는 코드를 실행하여 감지할 수 있습니다.

  • 모자이크 처리를 활성화하려면 detect.py를 수정하십시오.
<생략>

from utils.torch_utils import select_device, smart_inference_mode

#####################################추가된 코드#####################################
def blur_fun(frame, x, y, w, h) :
    try :
        face_img = frame(y:y+h, x:x+w) # 탐지된 얼굴 이미지 crop
        face_img = cv2.resize(face_img, dsize=(0, 0), fx=0.04, fy=0.04) # 축소
        face_img = cv2.resize(face_img, (w, h), interpolation=cv2.INTER_AREA) # 확대
        frame(y:y+h, x:x+w) = face_img # 탐지된 얼굴 영역 모자이크 처리
        return frame
    except :
        return frame
###################################################################################

@smart_inference_mode()
def run(
        weights=ROOT / 'yolov5s.pt',  # model.pt path(s)
        
        <생략>
        
):

    <생략>
    
            if len(det):
                # Rescale boxes from img_size to im0 size
                det(:, :4) = scale_coords(im.shape(2:), det(:, :4), im0.shape).round()

                ##############################특정 인물 제외한 얼굴 모자이크##################################
                tmp_list = det(:, :4).cpu().numpy()
                tmp_list = tmp_list.astype(np.int64)
                x1, y1, x2, y2, w, h = 0, 0, 0, 0, 0, 0
                class_num = det(:, 5).cpu().numpy()
                idx = 0
                for num in class_num :
                    if num == 0 :
                        x1, y1, x2, y2 = tmp_list(idx)(0), tmp_list(idx)(1), tmp_list(idx)(2), tmp_list(idx)(3)
                        ##
                        if idx < len(tmp_list)-1 :
                            x1_cmp, y1_cmp, x2_cmp, y2_cmp = tmp_list(idx+1)(0), tmp_list(idx+1)(1), tmp_list(idx+1)(2), tmp_list(idx+1)(3)
                        # if x
                        w = x2 - x1
                        h = y2 - y1
                        im0 = blur_fun(im0, x1, y1, w, h)
                    idx += 1
                ###############################################################################################
	<생략>
  • 욜로의 경우 바운딩 박스의 좌표를 텐서 데이터 타입으로 돌려주지만, 여기서는 좌표 값을 numpy 데이터 타입으로 변경하여 수정했습니다.

  • FaceNet 모델의 경우 face_recognition.py 파일을 통해서도 인식이 가능합니다.

  • face_recognition.py 파일도 수정되어 모자이크 처리가 가능합니다.

(생략)

        ########################################################################
        # 영상 프레임 너비
        width = video_capture.get(cv2.CAP_PROP_FRAME_WIDTH)
        # 영상 프레임 높이
        height = video_capture.get(cv2.CAP_PROP_FRAME_HEIGHT)
        # 초당 영상 프레임
        fps = video_capture.get(cv2.CAP_PROP_FPS)
        # 저장 동영상 코덱 정의
        fourcc = cv2.VideoWriter_fourcc(*'XVID')
        # 저장 영상 파일명 정의
        ##########################
        from pytz import timezone
        from datetime import datetime
        today = datetime.now(timezone('Asia/Seoul'))
        dt_string = today.strftime('%m/%d/%H:%M.avi')
        filename="yong18_90.avi"
        #filename1 = dt_string
        #out = cv2.VideoWriter(filename1, fourcc, fps, (int(width), int(height)))
        out = cv2.VideoWriter(filename, fourcc, fps, (int(width), int(height)))
        ########################################################################

        print('Start Recognition')

        while True:
            (생략)
                    try:
                        # inner exception
                        if xmin <= 0 or ymin <= 0 or xmax >= len(frame(0)) or ymax >= len(frame):
                            print('Face is very close!
') continue cropped.append(frame(ymin:ymax, xmin:xmax,:)) cropped(i) = facenet.flip(cropped(i), False) scaled.append(np.array(Image.fromarray(cropped(i)).resize((image_size, image_size)))) scaled(i) = cv2.resize(scaled(i), (input_image_size,input_image_size), interpolation=cv2.INTER_CUBIC) scaled(i) = facenet.prewhiten(scaled(i)) scaled_reshape.append(scaled(i).reshape(-1,input_image_size,input_image_size,3)) feed_dict = {images_placeholder: scaled_reshape(i), phase_train_placeholder: False} emb_array(0, :) = sess.run(embeddings, feed_dict=feed_dict) predictions = model.predict_proba(emb_array) best_class_indices = np.argmax(predictions, axis=1) best_class_probabilities = predictions(np.arange(len(best_class_indices)), best_class_indices) ###################쓰레시홀드 수정###################### if best_class_probabilities>0.90: ###################쓰레시홀드 수정###################### #cv2.rectangle(frame, (xmin, ymin), (xmax, ymax), (0, 255, 0), 2) #boxing face for H_i in HumanNames: if HumanNames(best_class_indices(0)) == H_i: result_names = HumanNames(best_class_indices(0)) print("Predictions : ( name: {} , accuracy: {:.3f} )".format(HumanNames(best_class_indices(0)),best_class_probabilities(0))) #cv2.rectangle(frame, (xmin, ymin-20), (xmax, ymin-2), (0, 255,255), -1) # cv2.putText(frame, result_names, (xmin,ymin-5), cv2.FONT_HERSHEY_COMPLEX_SMALL, # 1, (0, 0, 0), thickness=1, lineType=1) ############################################ if result_names !
= 'yong' : face_img = frame(ymin:ymin+(ymax-ymin), xmin:xmin+(xmax-xmin)) # 탐지된 얼굴 이미지 crop face_img = cv2.resize(face_img, dsize=(0, 0), fx=0.04, fy=0.04) # 축소 face_img = cv2.resize(face_img, ((xmax-xmin), (ymax-ymin)), interpolation=cv2.INTER_AREA) # 확대 frame(ymin:ymin+(ymax-ymin), xmin:xmin+(xmax-xmin)) = face_img # 탐지된 얼굴 영역 모자이크 처리 #################### ######################## else : # 모르는 사람 인식 했을때 #cv2.rectangle(frame, (xmin, ymin), (xmax, ymax), (0, 255, 0), 2) #cv2.rectangle(frame, (xmin, ymin-20), (xmax, ymin-2), (0, 255,255), -1) # cv2.putText(frame, "?", (xmin,ymin-5), cv2.FONT_HERSHEY_COMPLEX_SMALL, # 1, (0, 0, 0), thickness=1, lineType=1) ##########################모자이크 코드 삽입########################## face_img = frame(ymin:ymin+(ymax-ymin), xmin:xmin+(xmax-xmin)) # 탐지된 얼굴 이미지 crop face_img = cv2.resize(face_img, dsize=(0, 0), fx=0.04, fy=0.04) # 축소 face_img = cv2.resize(face_img, ((xmax-xmin), (ymax-ymin)), interpolation=cv2.INTER_AREA) # 확대 frame(ymin:ymin+(ymax-ymin), xmin:xmin+(xmax-xmin)) = face_img # 탐지된 얼굴 영역 모자이크 처리 ###################################################################### except: print("error") (생략) #################################################################### #out.write(frame) out.write(frame) #################################################################### (생략)
  • 욜로 모델의 경우 감지 후 이미지를 저장하는 코드가 기본적으로 포함되어 있지만 FaceNet은 포함되어 있지 않습니다.

    그래서 OpenCV를 사용하여 이미지를 저장하는 코드를 작성했습니다.

  • 그리고 FaceNet이 특정인의 이름과 다를 경우 모든 모자이크를 처리하도록 코드가 작성되었습니다.

5. 활동 결과

  • 후회했던 것 : 모든 모델이 같은 수의 에폭으로 진행할 수 없기 때문에 모든 에포크에서 가장 잘 훈련된 yolov5s 모델이 가장 잘 수행되었습니다.

    조건이 같지 않아 성능이 좋은 모델을 비교하고 선택할 수 없어 아쉬움이 남았다.

  • 평가 1 : 각 모델에 대해 모자이크 처리 코드를 포함한 탐지 파일을 실행하여 올바르게 작동하는지 확인했습니다.

  • 이번 프로젝트에서는 실시간 적용이 아닌 영상으로 테스트를 진행했습니다.

  • YOLOv5의 결과
yolov5의 결과 영상
  • YOLOv5m 결과
yolov5m 결과 비디오
  • YOLOv7 결과
yolov7 결과 비디오
  • FaceNet 결과
FaceNet 결과 비디오

6. 종료

  • 이전 야생 동물 기사에서 프로젝트는 데이터 수집, 분석 및 태깅에 중점을 두었지만 이 프로젝트에서는 다양한 모델을 탐색하고 사용할 수 있었습니다.

  • 인공지능 모델을 생성하고 인식하도록 설계된 코드를 직접 분할하여 인공지능의 진화를 연구할 수 있었습니다.

  • 그 다음에는 성능이 좋은 하드웨어가 있으면 프로젝트 결과를 실시간으로 실행해보고 싶어요.