셀럽미: 닮은 아이돌 찾기 서비스(https://celebme.net) 의 2024년 맞이 업데이트의 두번째 이야기입니
지난 글에서 이미지 수집을 다뤘었는데요~
* 지난 글: 셀럽미: 닮은 아이돌 찾기 2024년 맞이 업데이트(1/3) – 이미지 수집
이번엔 수집된 이미지를 전처리하는, 가공하는 내용을 다뤄보겠습니다.
얼굴영역 크롭 배경
우선 아래의 이미지를 한번 볼까요?
이 이미지는 여자 아이돌 김세정씨를 검색했을 때 수집된 이미지 중 일부인데요.
한 이미지 내에 김세정씨 외에 사내맞선의 주인공인 안효섭씨도 같이 포함된 걸 볼 수 있어요.
여자 아이돌 김세정씨만 사진에서 발췌한다면 당연히 모델 학습의 정확도가 올라갈 텐데요~
이 과정을 자동화해본다면 다음과 같은 순서로 이뤄지게 됩니다.
- 이미지 내의 모든 얼굴 영역을 추출
- 한 이미지 내에는 한 사람의 얼굴이 포함된 이미지만 남기고 나머지는 버림
- 한 사람의 이미지의 퀄리티가 좋은 경우만 선별하여 저장
단순해 보이는 위 과정으로 자동화해서 저장해본다면, 위와 같이 두 사람 이상이 포함된 이미지는 버려지게 됩니다.
두 명이 속한 이미지는 아니지만, 아래와 같은 경우는 어떨까요?
얼굴이 속한 부분만 크롭해서 저장한다면 모델의 정확도를 늘릴 수 있습니다.
얼굴만 크롭해서 저장하면 아래와 같은 결과를 볼 수 있어요.
얼굴영역 크롭 코드
위의 얼굴영역 크롭 배경에 기술된 과정을 따라 자동화한 코드는 아래와 같습니다.
# %pip install --upgrade pip setuptools wheel opencv-python
# %pip install git+https://github.com/serengil/retinaface.git
# sudo apt install -y libhdf5-dev
import os
import cv2
import numpy as np
from retinaface import RetinaFace
os.environ["CUDA_VISIBLE_DEVICES"] = "-1"
model = RetinaFace.build_model()
def detect_and_save_faces(input_image_path, output_folder, face_idx):
# Load the input image
image = cv2.imread(input_image_path)
try:
# Detect faces using the SSD model
detected_faces = RetinaFace.extract_faces(
input_image_path,
threshold=0.97,
model=model,
align=True,
align_first=True,
allow_upscaling=True,
expand_face_area=10,
)
if len(detected_faces) > 1:
# print(f'{input_image_path} has more than 1 face.')
return face_idx
# Create the output folder if it doesn't exist
if not os.path.exists(output_folder):
os.makedirs(output_folder)
# Loop through each detected face and save it as a 300x300 PNG file
for i, face_info in enumerate(detected_faces):
face = face_info
# print(face)
# print("resizing..")
maxwidth, maxheight = 300, 300
f1 = maxwidth / face.shape[1]
f2 = maxheight / face.shape[0]
f = min(f1, f2)
dim = (int(face.shape[1] * f), int(face.shape[0] * f))
face_resized = cv2.resize(face, dim, interpolation=cv2.INTER_AREA)
face_rgb = cv2.cvtColor(face_resized, cv2.COLOR_BGR2RGB)
# Create a black image with the target size
padded_image = np.zeros((300, 300, 3), dtype=np.uint8)
padding_rows = (300 - dim[1]) // 2
padding_cols = (300 - dim[0]) // 2
# Add the resized image to the padded image, with padding on the left and right sides
padded_image[padding_rows : padding_rows + dim[1], padding_cols : padding_cols + dim[0]] = face_rgb
face_idx += 1
# Save the face as a PNG file in the output folder
output_path = os.path.join(output_folder, f"face_{face_idx}.png")
cv2.imwrite(output_path, padded_image)
# print(f"{len(detected_faces)} faces detected and saved to {output_folder}")
except Exception as e:
print(str(e))
return face_idx
import os
path_img = "images"
path_faces = "faces"
# # test
# input_image_path = '01.png'
# output_folder = 'output/'
# detect_and_save_faces(input_image_path, output_folder, 0)
for gender in sorted(os.listdir(path_img)):
path_gender = os.path.join(path_img, gender)
for name in sorted(os.listdir(path_gender)):
if os.path.exists(os.path.join(path_faces, gender, name)):
continue
path_name = os.path.join(path_img, gender, name)
face_idx = 0
for path_file in sorted(os.listdir(path_name)):
path_img_file = os.path.join(path_name, path_file)
if os.path.getsize(path_img_file) < 100000:
continue
# print(path_img_file)
# input_image_path = '01.png'
output_folder = os.path.join(path_faces, gender, name)
face_idx = detect_and_save_faces(path_img_file, output_folder, face_idx)
위 코드의 처리 과정은 아래와 같습니다.
- images/[성별]/[아이돌이름]/[그림파일명] 폴더구조를 가진 이미지 파일들을 로드
- 로드한 이미지에서 얼굴이 포함된 개수를 집계
- 얼굴수가 1보다 크면 스킵
- 그렇지 않다면, 해당 얼굴만큼 이미지를 크롭
- 이미지를 크롭할 때, 얼굴부분의 각도를 평평하게 transform
- 넓이나, 높이 중 긴 부분을 300 픽셀로 리사이징
- 300×300 픽셀이 되도록 나머지 부분은 검정색으로 padding하여 채우기
- 결과물인 300×300 픽셀의 얼굴이미지를 faces/[성별]/[아이돌이름]/[얼굴번호] 밑으로 저장
비교적 코드가 길지 않지만, 단순하지는 않아보이네요~
그래도 꽤나 성가시고 손이 많이 가는 프로세스였는데, 자동화해서 이렇게 잘 돌아가는 코드를 보면 뿌듯함이 올라옵니다.
이미지 수집과 얼굴영역 크롭 결과
이전 글에서 작성한 코드로 수집된 이미지에 목록과 사이즈에요.
도합 75000 장에 달하는 이미지를 수집했고, 사이즈로는 합쳐서 약 14GB의 사이즈를 수집했네요.
- 여자 아이돌 목록: https://github.com/kwontaeheon/kceleb_model/blob/main/women_label/labels.txt
- 남자 아이돌 목록: https://github.com/kwontaeheon/kceleb_model/blob/main/men_label/labels.txt
여자 아이돌 목록
- EXID 솔지
- EXID 하니
- EXID 혜린
- ITZY 류진
- ITZY 리아
- ITZY 예지
- ITZY 유나
- ITZY 채령
- 강미나
- 김세정
- 나인뮤지스 경리
- 뉴진스 다니엘
- 뉴진스 민지
- 뉴진스 하니
- 뉴진스 해린
- 뉴진스 혜인
- 다이아 기희현
- 다이아 예빈
- 다이아 유니스
- 다이아 은채
- 다이아 정채연
- 다이아 주은
- 라붐 소연
- 라붐 솔빈
- 라붐 진예
- 라붐 해인
- 러블리즈 이미주
- 레드벨벳 슬기
- 레드벨벳 아이린
- 레드벨벳 예리
- 레드벨벳 웬디
- 레드벨벳 조이
- 르세라핌 카즈하
- 르세라핌 허윤진
- 르세라핌 홍은채
- 마마무 솔라
- 마마무 화사
- 브레이브걸스 민영
- 브레이브걸스 유나
- 브레이브걸스 유정
- 브레이브걸스 은지
- 블랙핑크 로제
- 블랙핑크 리사
- 블랙핑크 제니
- 블랙핑크 지수
- 설현
- 소녀시대 윤아
- 소녀시대 태연
- 소녀시대 티파니
- 소녀시대 효연
- 아이브 가을
- 아이브 레이
- 아이브 리즈
- 아이브 안유진
- 아이브 이서
- 아이브 장원영
- 아이유
- 아이즈원 권은비
- 아이즈원 김채원
- 아이즈원 이채연
- 에스파 닝닝
- 에스파 윈터
- 에스파 지젤
- 에스파 카리나
- 엔믹스 규진
- 엔믹스 릴리
- 엔믹스 배이
- 엔믹스 설윤
- 엔믹스 지니
- 엔믹스 지우
- 엔믹스 해원
- 여자아이들 미연
- 여자아이들 민니
- 여자아이들 소연
- 여자아이들 슈화
- 여자아이들 우기
- 여자친구 유주
- 여자친구 은하
- 트와이스 나연
- 트와이스 모모
- 트와이스 사나
- 트와이스 정연
- 트와이스 지효
- 하이키 리이나
- 하이키 서이
- 하이키 옐
- 하이키 휘서
남자 아이돌 목록
- BTS RM
- BTS 뷔
- BTS 슈가
- BTS 정국
- BTS 제이홉
- BTS 지민
- BTS 진
- EXO 디오
- NCT 마크
- NCT 재현
- WINNER 강승윤
- WINNER 송민호
- WINNER 이승훈
- 더보이즈 뉴
- 더보이즈 상연
- 더보이즈 선우
- 더보이즈 에릭
- 더보이즈 영훈
- 더보이즈 제이콥
- 더보이즈 주연
- 더보이즈 주학년
- 더보이즈 케빈
- 더보이즈 큐
- 더보이즈 현재
- 라이즈 성찬
- 라이즈 소희
- 라이즈 쇼타로
- 라이즈 승한
- 라이즈 앤톤
- 라이즈 원빈
- 라이즈 은석
- 몬스타엑스 기현
- 몬스타엑스 민혁
- 몬스타엑스 셔누
- 몬스타엑스 아이엠
- 몬스타엑스 주헌
- 몬스타엑스 형원
- 블락비 박경
- 블락비 지코
- 블락비 피오
- 비스트 양요섭
- 비스트 용준형
- 비스트 윤두준
- 비투비 이창섭
- 샤이니 온유
- 샤이니 키
- 샤이니 태민
- 세븐틴 민규
- 세븐틴 에스쿱스
- 세븐틴 원우
- 세븐틴 준
- 세븐틴 호시
- 슈퍼주니어 신동
- 스트레이키즈 리노
- 스트레이키즈 방찬
- 스트레이키즈 승민
- 스트레이키즈 창빈
- 스트레이키즈 필릭스
- 스트레이키즈 한
- 스트레이키즈 현진
- 아스트로 MJ
- 아스트로 라키
- 아스트로 문빈
- 아스트로 윤산하
- 아스트로 진진
- 아스트로 차은우
- 워너원 강다니엘
- 워너원 옹성우
- 워너원 황민현
- 인피니트 엘
- 제국의아이들 김동준
- 제국의아이들 임시완
- 제국의아이들 황광희
- 투모로우바이투게더 수빈
- 투모로우바이투게더 연준
이번엔 얼굴영역 크롭 결과 이미지 목록과 사이즈를 살펴볼까요?
중간에 모델결과물이 섞여있어서 모델 결과 용량 약 240MB 를 제외하면, 약 25000개 수준의 얼굴이미지 파일과, 용량으로는 대략 3.3GB 로 줄어든걸 확인할 수 있어요.
- 얼굴영역 크롭 전
- 전체 아이돌 이미지 개수: 75220
- 이미지 크기 합: 14GB
- 얼굴영역 크롭 후 전체 아이돌 이미지 개수: 25242
- 전체 아이돌 이미지 개수: 25242 (약 53000개 감소)
- 이미지 크기 합: 3.3GB (약 11GB 감소)
마무리
이번 글에서는 셀럽미: 닮은 아이돌 찾기 2024년 맞이 업데이트를 위해 수집된 이미지를 얼굴 영역 기준으로 크롭하는 과정을 다뤄봤는데요.
코드를 전체적으로 담았기 때문에 이 과정에 대해 궁금하신 분들에게 도움이 되셨다면 좋겠습니다.
다음 글에서는 이 이미지들을 활용해서 닮은 아이돌 찾기 모델을 만든 과정을 다뤄볼게요~