본 글은 keras 공식 홈페이지의 스테이블 디퓨전 파인튜닝 예시 코드를 기반으로 작성됐습니다.
함께 학습한 안효주님의 블로그 바로가기
실제 사람 사진 1장과 유사한 얼굴을 띈 메이플스토리 캐릭터 사진 1장 한 묶음으로 준비가 돼 있습니다.
파일명은 다음과 같습니다.
data/man_1.jpg # 메이플 캐릭터 사진
data/man_real_1.png # 실제 사람 사진
아래 코드로 실제 사람의 이미지 데이터의 주소를 result_data에 담았습니다.
import cv2
import mediapipe as mp
import numpy as np
import os
import pandas as pd
# CSV 파일에 저장할 결과 데이터프레임을 초기화합니다.
result_data = []
# data 폴더에서 real을 포함한 이미지 파일 경로를 가져오는 함수
def get_image_paths(directory):
image_paths = []
for root, dirs, files in os.walk(directory):
for file in files:
if (
file.lower().endswith((".jpg", ".jpeg", ".png", ".bmp", ".gif"))
and "real" in file.lower()
):
image_paths.append(os.path.join(root, file))
return image_paths
image_paths = get_image_paths("./data")
그 후 각 이미지를 순회하며 mediapipe를 사용하여 사람의 얼굴 특성을 하드코딩으로 추출했습니다.
관련 글은 daily study에 mediapipe글을 참고해 주세요
for image_path in image_paths:
image = cv2.imread(image_path)
# Mediapipe 초기화
mp_face_mesh = mp.solutions.face_mesh
face_mesh = mp_face_mesh.FaceMesh()
# .... 특성추출 및 이미지 경로 저장
new_data = {
"image_path": new_image_path,
"Eye Ratio": eye_ratio,
"Face Ratio": face_ratio,
"Eyebrow Ratio": eyebrow_ratio,
"Lip Width": lip_width,
"Nose Width": nose_width,
}
result_data.append(new_data)
저장을 위해 데이터 프레임으로 변환 후 각 수치의 33, 67퍼센트에 해당하는 값을 기점으로 각 얼굴의 특성을 분류하였습니다.
# 데이터프레임으로 변환
result_df = pd.DataFrame(result_data)
# Sort the DataFrame by 'Eye Ratio' column
result_df = result_df.sort_values(by="Eye Ratio")
# # 처리할 수치 열의 목록과 해당 별칭 정의
column_aliases = {
"Eye Ratio": "눈",
"Face Ratio": "얼굴",
"Eyebrow Ratio": "눈썹",
"Lip Width": "입",
"Nose Width": "코",
}
# 각 수치 열에 대한 사분위수 기반으로 라벨 생성
for col, alias in column_aliases.items():
bottom_quantile = result_df[col].quantile(0.33)
top_quantile = result_df[col].quantile(0.67)
# 경계선 값 출력
print(f"Bottom Quantile ({col}): {bottom_quantile}")
print(f"Top Quantile ({col}): {top_quantile}")
result_df[alias + "_label"] = "중" + alias # 기본값으로 중간 라벨 설정
result_df.loc[result_df[col] <= bottom_quantile, alias + "_label"] = "소" + alias
result_df.loc[result_df[col] > top_quantile, alias + "_label"] = "대" + alias
# 'caption' 열 생성: 라벨 열을 이용하여 생성
label_columns = [alias + "_label" for alias in column_aliases.values()]
result_df["caption"] = "메이플캐릭터," + result_df[label_columns].apply(
lambda row: ",".join(row), axis=1
)
selected_columns = ["image_path", "caption"]
new_df = result_df[selected_columns]
# 수정 함수 정의
def modify_caption(row):
if "woman" in row["image_path"]:
return row["caption"] + ",woman"
else:
return row["caption"] + ",man"
# apply 함수를 사용하여 caption 열 수정
new_df["caption"] = new_df.apply(modify_caption, axis=1)
# 새로운 DataFrame을 CSV 파일로 저장
new_df.to_csv("dataset.csv", index=False)
최종적인 dataset.csv는 총 두개의 컬럼으로 캐릭터 이미지 경로인 image_path, 얼굴의 특성이 담긴 txt인 caption열로 구성이 됩니다.
image_path,caption
./data/man_15.jpg,"메이플캐릭터,소눈,대얼굴,소눈썹,대입,대코,man"
./data/woman_25.jpg,"메이플캐릭터,소눈,소얼굴,소눈썹,중입,소코,woman"
./data/man_23.jpg,"메이플캐릭터,소눈,대얼굴,소눈썹,대입,대코,man"
댓글