IT/개발

Deepface로 얼굴 속성 분석하기 (얼굴, 성별, 나이, 인종, 감정 인식)

빗자루검 2025. 7. 17. 17:53
반응형

페이스북 인공지능 팀에서 만든 deepface는 벌써 나온지 꽤 시간이 흘렀습니다. 

초기에 페북에서 사용자 사생활 침해가 어쩌고 하면서 말이 많았었죠. 

어쨌던 저쨌던 기술 자체는 상당이 유용한 건 사실입니다. 

파이썬 패키지로도 제공되고 있어 사용도 간단하죠. 

 

주요 기능은 크게 얼굴 속성 분석얼굴 인식으로 나눌 수 있습니다.

 

DeepFace.analyze() 함수를 통해 이미지나 영상 속 인물의 여러 가지 속성을 한 번에 검출할 수 있습니다.

 

공식 깃허브 저장소는 다음과 같습니다.

https://github.com/serengil/deepface

 

GitHub - serengil/deepface: A Lightweight Face Recognition and Facial Attribute Analysis (Age, Gender, Emotion and Race) Library

A Lightweight Face Recognition and Facial Attribute Analysis (Age, Gender, Emotion and Race) Library for Python - serengil/deepface

github.com

 

 

1. 얼굴 속성 

- 나이 (Age): 20대, 30대 등 예측

 

- 성별 (Gender): 'Man' 또는 'Woman'으로 예측

 

- 감정 (Emotion): 'angry'(화남), 'fear'(두려움), 'neutral'(중립), 'sad'(슬픔), 'disgust'(역겨움), 'happy'(행복), 'surprise'(놀람)의 7가지 감정 분석

 

- 인종 (Race): 'asian'(아시아인), 'white'(백인), 'middle eastern'(중동인), 'indian'(인도인), 'latino'(라틴계), 'black'(흑인) 등으로 예측

2. 얼굴 인식 

- 얼굴 검증 (Verification): DeepFace.verify()   
두 개의 얼굴 사진이 동일 인물인지 아닌지 1:1로 비교하고 판단


- 얼굴 찾기 (Find): DeepFace.find()

지정된 이미지 속 얼굴과 데이터베이스(폴더)에 있는 여러 이미지들을 비교하여 가장 유사한 얼굴들을 찾아냄


- 얼굴 표현 (Representation): DeepFace.represent()  

얼굴 이미지를 벡터(Embedding)로 변환, 빠르고 효율적인 얼굴 비교 및 검색에 사용

 

3. 패키지 설치 

pip instll deepface
pip install tf-keras

코드를 실행하면 사용하면 자동으로 다음 학습모델을 다운로드 받습니다. 
age_model_weights.h5
gender_model_weights.h5
race_model_single_batch.h5
facial_expression_model_weights.h5

 

4. 간단한 예제 코드 

 

사진 이미지를 입력하여 얼굴을 분석 해 보겠습니다. 

얼굴을 찾고 각 정보를 찾아서 박스아래 표시합니다. 

 


import cv2
from deepface import DeepFace

def analyze_and_draw_faces(input_image_path, output_image_path):
    # 이미지 읽기
    img = cv2.imread(input_image_path)
    if img is None:
        print("이미지를 불러올 수 없습니다.")
        return

    # 얼굴 분석
    results = DeepFace.analyze(img_path = input_image_path, actions = ['age', 'gender', 'race', 'emotion'], enforce_detection=False)

    # 여러 얼굴이 있을 경우 리스트로 반환됨
    if not isinstance(results, list):
        results = [results]

    for face in results:
        region = face['region']
        x, y, w, h = region['x'], region['y'], region['w'], region['h']
        # 얼굴 박스 그리기
        # 밝은 파란색(BGR: 255, 200, 100)으로 얼굴 박스 그리기
        cv2.rectangle(img, (x, y), (x+w, y+h), (255, 200, 100), 2)

        # gender 확률에서 높은 값을 선택하고, 소수점 2자리까지 표시
        gender_dict = face.get('gender', {})
        if isinstance(gender_dict, dict):
            gender_label = max(gender_dict, key=gender_dict.get)
            gender_prob = gender_dict[gender_label]
            gender_str = f"{gender_label}({gender_prob:.2f})"
        else:
            gender_str = str(face.get('gender', ''))

        age = face['age']
        emotion = max(face['emotion'], key=face['emotion'].get)
        race = max(face['race'], key=face['race'].get)
        text = f"gender: {gender_str}  age: {age}\nrace: {race}  emotion: {emotion}"

        # 텍스트를 얼굴 박스의 왼쪽 아래에 약간 공간을 두고 출력
        text_lines = text.split('\n')
        font = cv2.FONT_HERSHEY_SIMPLEX
        font_scale = 0.5
        thickness = 1
        color = (0, 128, 255)  # 밝은 빨강색 (BGR: 0, 128, 255)

        # 각 줄의 높이 계산 (폰트 크기와 두께에 따라)
        (text_width, text_height), baseline = cv2.getTextSize(text_lines[0], font, font_scale, thickness)
        line_height = text_height + baseline

        # 텍스트 시작 위치 계산 (박스 왼쪽 아래에서 약간 띄움)
        text_x = x
        text_y = y + h + 10 + line_height  # 박스 아래에서 10px 띄우고 첫 줄 높이만큼 더함

        for i, line in enumerate(text_lines):
            cv2.putText(
                img,
                line,
                (text_x, text_y + i * line_height),
                font,
                font_scale,
                color,
                thickness,
                cv2.LINE_AA
            )

    # 결과 이미지 저장
    cv2.imwrite(output_image_path, img)
    print(f"분석 결과가 {output_image_path}에 저장되었습니다.")

#  사용법
analyze_and_draw_faces("./images/m_news_zum_com_img008.jpg", "m_news_zum_com_img008_out.jpg")

 

 

결과를 확인해 볼까요??

 

 

GPU를 돌리지 않아도 1,2 fps 정도의 프레임 처리는 가능하겠네요. 

여기저기 쓸데가 많아 보입니다. 

 

반응형