haarcascade_frontalface 알고리즘을 이용한 face cropping

장영준·2023년 3월 23일
0

youtuber-look-alike

목록 보기
2/3

haarcascade_frontalface 는 OpenCV에서 제공하는 얼굴 검출 알고리즘 중 하나이다. 해당 알고리즘은 Haar-like 특징을 사용하여 이미지에서 얼굴을 인식한다.

Haar-like 특징은 이미지에서 주어진 위치에서 픽셀 강도를 계산하여 특징 벡터를 만드는데 사용된다.
이는 여러 개의 직사각형 영역을 가지고 있는데, 이 영역의 픽셀 값들의 합을 이용하여 특징 값을 계산한다. 이때, 직사각형의 영역의 크기와 위치, 그리고 값의 부호가 특징 값에 영향을 미친다.
예시로, 머리카락의 윤곽을 따라 하얀색(살색)과 검은색으로 번갈아 가며 나타내는 특징을 생각해보면, 얼굴과 머리카락 구분에 용이하다.


해당 알고리즘을 이용하여, 인물 사진의 얼굴만 cropping 하는 함수를 만들어 적용하고 파일을 저장하는 작업까지 진행해보았다.

  1. haarcascade_frontalface_default.xml 파일을 검색하고 저장한다.
  2. 코드 작성
!pip install opencv-python

import numpy as np
import pandas as pd
import cv2
import os

# 원본 파일 가져올 root 디렉토리
import_root_path = '/Users/jang-youngjoon/dev-projects/youtuber-look-alike/crawled-image'

# 전처리된 파일 저장할 root 디렉토리
save_root_path = '/Users/jang-youngjoon/dev-projects/youtuber-look-alike/pre-processed-image'

celeb_name = input('가져올 연예인의 이름을 입력하세요: ')
celeb_name_to_en = ''

if celeb_name == '송혜교':
    celeb_name_to_en = 'shg'
elif celeb_name == '이도현': 
      celeb_name_to_en = 'idh'
elif celeb_name == '임지연':
      celeb_name_to_en = 'ijh'
elif celeb_name == '신예은':
      celeb_name_to_en = 'she'
      
import_path = os.path.join(import_root_path, celeb_name_to_en)
image_list = os.listdir(import_path)

save_path = str(os.path.join(save_root_path, celeb_name_to_en))

# 얼굴 crop하는 함수
def crop_face(image, name):
    # face_cascade 모델 사용
    face_cascade = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    faces = face_cascade.detectMultiScale(gray, 1.3, 5)

    for (x, y, w, h) in faces:
        cropped_image = image[y : y+h, x : x+w]
        resized_image = cv2.resize(cropped_image, (180, 180))
        cv2.imwrite(os.path.join(save_path, name), resized_image)
        print(f"{celeb_name_to_en} image cropped & saved" )

# 실제 얼굴 crop 실행
for image_name in image_list:
    # .DS Store 파일 확인
    if 'jpg' in image_name:
        original_image = cv2.imread(os.path.join(import_path, str(image_name)))
        # 백색 이미지 방지 할라했는데 안됨,,,
        if (type(original_image) != 'NoneType' or original_image != None) :
            crop_face(original_image, image_name)   
        else:
            continue
    else:
        continue

이렇게 작성하여 얼굴 이미지를 crop하고 파일을 저장하는 것까지 완성했다. 하지만, 백색 이미지일때의 대처는 해결하지 못해서 손수 삭제하고 구현했다.

profile
배움의 개발자

0개의 댓글