DEEP.I - Lab

오프라인 공간의 지능화를 꿈꾸는 딥아이 연구실입니다.

Python/Python

[Python] 파이썬 OpenCV를 이용한 성별 및 나이 예측하기

Jongwon Kim 2021. 1. 6. 17:29
반응형

Concept

지난 포스팅에 이어, 얼굴 인식 후 적용할 수 있는 성별 및 나이 예측 알고리즘입니다. 모두 파이썬 기반 OpenCV를 통해 구현하였으며 지난 포스팅을 참고하시면 기본적인 얼굴 탐지 알고리즘을 구현할 수 있습니다.

 

deep-eye.tistory.com/18

 

[Python] 파이썬 OpenCV를 이용한 얼굴 인식

과거 얼굴인식은 첩보영화나 CSI와 같은 드라마에서 범죄자를 찾는데 활용되는 신기술로 인식되었으나, 머신러닝과 하드웨어의 발전으로 이젠 일상에서 쉽게 접할 수 있게 되었습니다. 현재 얼

deep-eye.tistory.com

 

Algorithm

비교적 단순한 구조를 가지는 CNN 기반 신경망 모델입니다. 얼굴 탐지를 통해 예측된 얼굴의 위치 (경계 상자)를 기준으로 이미지를 추출한 뒤, 성별 또는 연령 데이터에 학습된 분류기에 입력하는 방식입니다.

 

MNIST나 강아지 고양이 분류 모델과 구조적으로 동일하며 그림 1과 같이 입력 영상과 출력 클래스가 다를 뿐이죠.

 

그림 1. Gender Recognition Through Face Using Deep Learning (ICCIDS 2018)

 

SourceCode

전체 코드는 깃허브를 통해 공유하고 있습니다. 링크를 참조해주세요.

github.com/DEEPI-LAB/python-opencv-face-detector.git

 

DEEPI-LAB/python-opencv-face-detector

Contribute to DEEPI-LAB/python-opencv-face-detector development by creating an account on GitHub.

github.com

git clone https://github.com/DEEPI-LAB/python-opencv-face-detector.git

 

구글 드라이브 링크를 통해 학습된 가중치를 다운받으세요. 얼굴 탐지기, 성별 분류기, 연령 분류기 학습 가중치이며 90mb 정도 됩니다. 이후 코드가 작성될 경로로 복사해주시면 됩니다.

 

1.  사전학습된 가중치 파일 불러오기

MODEL_MEAN_VALUES = (78.4263377603, 87.7689143744, 114.895847746)

# 언령 예측 모델 불러오기
age_net = cv2.dnn.readNetFromCaffe(
	'deploy_age.prototxt',
	'age_net.caffemodel')

# 성별 예측 모델 불러오기
gender_net = cv2.dnn.readNetFromCaffe(
	'deploy_gender.prototxt',
	'gender_net.caffemodel')

# 연령 클래스
age_list = ['(0 ~ 2)','(4 ~ 6)','(8 ~ 12)','(15 ~ 20)',
            '(25 ~ 32)','(38 ~ 43)','(48 ~ 53)','(60 ~ 100)']
# 성별 클래스
gender_list = ['Male', 'Female']

readNetFromCaffe 함수로 연령과 성별 예측 모델을 불러옵니다. 학습된 클래스는 age_listgender_list로 표현됩니다. 연령의 경우 분포도가 조금 신기합니다. 20세 이하 클래스에 대해선 분포도가 촘촘하네요.

 

만약 최종적으로 예측된 age_net의 결과가 1, gender_net의 결과가 0이라면 성별은 남자, 연령은 4 ~ 6세로 예측된 겁니다.

 

2. 인식된 얼굴을 기준으로 성별 및 연령 예측하기

for box in results:

    # 예측된 얼굴의 위치
    x, y, w, h = box
    # 얼굴 이미지 추출
    face = img[int(y):int(y+h),int(x):int(x+h)].copy()
    # 성별 및 연령 예측을 위한 이미지 변환 맟 전처리
    blob = cv2.dnn.blobFromImage(face, 1, (227, 227), MODEL_MEAN_VALUES, swapRB=False)
    
    # gender detection
    gender_net.setInput(blob)
    gender_preds = gender_net.forward()
    # 가장 높은 Score값을 선정
    gender = gender_preds.argmax()
    # Predict age
    age_net.setInput(blob)
    age_preds = age_net.forward()
    # 가장 높은 Score값을 선정
    age = age_preds.argmax()
    
    info = gender_list[gender] +' '+ age_list[age]

    cv2.rectangle(img, (x,y), (x+w, y+h), (255,255,255), thickness=2)
    cv2.putText(img,info,(x,y-10),0, 0.5, (0, 255, 0), 1)

인식된 얼굴을 기준으로 성별과 연령 예측 모델을 입력한 뒤, cv2.putText()로 예측된 정보를 경계 상자 테두리에 입력해줍니다.

 

3. 전체 소스코드

# -*- coding: utf-8 -*-
"""
Created on Wed Nov 4 
@author: jongwon Kim 
         Deep.I Inc.
"""

import cv2

# 영상 검출기
def videoDetector(cam,cascade,age_net,gender_net,MODEL_MEAN_VALUES,age_list,gender_list):

    while True:

        # 캡처 이미지 불러오기
        ret,img = cam.read()
        # 영상 압축
        try:
            img = cv2.resize(img,dsize=None,fx=1.0,fy=1.0)
        except: break
        # 그레이 스케일 변환
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 
        # cascade 얼굴 탐지 알고리즘 
        results = cascade.detectMultiScale(gray,            # 입력 이미지
                                           scaleFactor= 1.1,# 이미지 피라미드 스케일 factor
                                           minNeighbors=5,  # 인접 객체 최소 거리 픽셀
                                           minSize=(20,20)  # 탐지 객체 최소 크기
                                           )

        for box in results:
            x, y, w, h = box
            face = img[int(y):int(y+h),int(x):int(x+h)].copy()
            blob = cv2.dnn.blobFromImage(face, 1, (227, 227), MODEL_MEAN_VALUES, swapRB=False)

            # gender detection
            gender_net.setInput(blob)
            gender_preds = gender_net.forward()
            gender = gender_preds.argmax()
            # Predict age
            age_net.setInput(blob)
            age_preds = age_net.forward()
            age = age_preds.argmax()
            
            info = gender_list[gender] +' '+ age_list[age]

            cv2.rectangle(img, (x,y), (x+w, y+h), (255,255,255), thickness=2)
            cv2.putText(img,info,(x,y-15),0, 0.5, (0, 255, 0), 1)


         # 영상 출력
        cv2.imshow('facenet',img)

        if cv2.waitKey(1) > 0: 

            break

# 사진 검출기
def imgDetector(img,cascade,age_net,gender_net,MODEL_MEAN_VALUES,age_list,gender_list):
    
    # 영상 압축
    img = cv2.resize(img,dsize=None,fx=1.0,fy=1.0)
    # 그레이 스케일 변환
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 
    # cascade 얼굴 탐지 알고리즘 
    results = cascade.detectMultiScale(gray,            # 입력 이미지
                                       scaleFactor= 1.5,# 이미지 피라미드 스케일 factor
                                       minNeighbors=5,  # 인접 객체 최소 거리 픽셀
                                       minSize=(20,20)  # 탐지 객체 최소 크기
                                       )        

    for box in results:

        x, y, w, h = box
        face = img[int(y):int(y+h),int(x):int(x+h)].copy()
        blob = cv2.dnn.blobFromImage(face, 1, (227, 227), MODEL_MEAN_VALUES, swapRB=False)
        
        # gender detection
        gender_net.setInput(blob)
        gender_preds = gender_net.forward()
        gender = gender_preds.argmax()
        # Predict age
        age_net.setInput(blob)
        age_preds = age_net.forward()
        age = age_preds.argmax()
        info = gender_list[gender] +' '+ age_list[age]
        cv2.rectangle(img, (x,y), (x+w, y+h), (255,255,255), thickness=2)
        cv2.putText(img,info,(x,y-15),0, 0.5, (0, 255, 0), 1)

    # 사진 출력
    cv2.imshow('facenet',img)  
    cv2.waitKey(10000)

# 얼굴 탐지 모델 가중치
cascade_filename = 'haarcascade_frontalface_alt.xml'
# 모델 불러오기
cascade = cv2.CascadeClassifier(cascade_filename)


MODEL_MEAN_VALUES = (78.4263377603, 87.7689143744, 114.895847746)

age_net = cv2.dnn.readNetFromCaffe(
	'deploy_age.prototxt',
	'age_net.caffemodel')

gender_net = cv2.dnn.readNetFromCaffe(
	'deploy_gender.prototxt',
	'gender_net.caffemodel')

age_list = ['(0 ~ 2)','(4 ~ 6)','(8 ~ 12)','(15 ~ 20)',
            '(25 ~ 32)','(38 ~ 43)','(48 ~ 53)','(60 ~ 100)']
gender_list = ['Male', 'Female']

# 영상 파일 
cam = cv2.VideoCapture('sample.mp4')
# 이미지 파일
img = cv2.imread('sample.jpg')

# 영상 탐지기
videoDetector(cam,cascade,age_net,gender_net,MODEL_MEAN_VALUES,age_list,gender_list )
# 사진 탐지기
# imgDetector(img,cascade,age_net,gender_net,MODEL_MEAN_VALUES,age_list,gender_list )

그림 2. 성별 및 연령 예측 결과

 

Your Best AI Partner DEEP.I
AI 바우처 공급 기업
객체 추적 및 행동 분석 솔루션 | 제조 생산품 품질 검사 솔루션 | AI 엣지 컴퓨팅 시스템 개발

인공지능 프로젝트 개발 외주 및 상담
E-mail: contact@deep-i.ai
Site: www.deep-i.ai
 

딥아이 DEEP.I | AI 기반 지능형 기업 솔루션

딥아이는 AI 기술의 정상화라는 목표를 갖고, 최첨단 딥러닝 기술 기반의 기업 솔루션을 제공하고 있으며, 이를 통해 고도의 AI 기반 객체 탐지, 분석, 추적 기능을 통합하여 다양한 산업 분야에

deep-i.ai

 

 

반응형