강의자료/머신러닝

[머신러닝활용]성별과 나이를 맞추는 인공지능

파아란 기쁨 2023. 1. 31. 12:33

tal Hassner 님이 만든 나이와 성별을 맞추는 모델을 사용하는 방법을 살펴 보겠습니다.

공식 홈페이지는 https://talhassner.github.io/home/ 입니다.

원본 소스는 https://github.com/GilLevi/AgeGenderDeepLearning/blob/master/AgeGenderDemo.ipynb 입니다.

참고한 소스는 [빵형의 개발도상국]님의 깃허브 https://github.com/kairess/age_gender_estimation/blob/master/main.py 입니다.

1. 실습환경

코랩 - https://colab.research.google.com/?hl=ko 

 

Google Colaboratory

 

colab.research.google.com

모델 다운로드 - https://github.com/GilLevi/AgeGenderDeepLearning/tree/master/models

 

GitHub - GilLevi/AgeGenderDeepLearning

Contribute to GilLevi/AgeGenderDeepLearning development by creating an account on GitHub.

github.com

여기서 3개의 모델을 다운로드 하여 구글 드라이브에 업로드 해 놓자.(코랩에 업로드 하는 것 보다 구글 드라이버에 업로드 후 드라이브 마운트 해서 사용하는 것이 더 빠르다.)

내 드라이브> Colab Notebooks > model 디렉토리에 업로드 했습니다.

https://github.com/GilLevi/AgeGenderDeepLearning/tree/master/age_net_definitions 에서 deploy.prototxt 다운로드후 업로드

 

GitHub - GilLevi/AgeGenderDeepLearning

Contribute to GilLevi/AgeGenderDeepLearning development by creating an account on GitHub.

github.com

https://github.com/GilLevi/AgeGenderDeepLearning/tree/master/gender_net_definitions 에서 deploy.prototxt 다운로드 후 업로드

두개의 이름이 같으므로 deploy_age, deploy_gender 와 같이 이름 변경하여 업로드 하자.

 

2. 구글 드라이브 마운트

from google.colab import drive
drive.mount('/content/drive')

좌측의 탐색기에 drive 디렉토리가 보인다.

3. cv2,glov,dlib 라이브러리 임포트

from google.colab.patches import cv2_imshow
import cv2,glob,dlib

4. 나이와 성별을 구분하는 리스트를 생성

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

원본소스코드에서 사용한 리스트를 재사용했습니다. 만약 0번 인덱스라면 0~2세,1번 인덱스 값을 리턴한다면 4~6세... 와 같은 의미를 포함합니다.

모델을 생성하기 위해 사용한 데이터이미지 : https://talhassner.github.io/home/projects/Adience/Adience-data.html

 

Face Image Project - Data

 

talhassner.github.io

 

5. 모델 로딩

- Loading the age network

age_net_pretrained='/content/drive/MyDrive/Colab Notebooks/model/age_net.caffemodel'
age_net_model_file='/content/drive/MyDrive/Colab Notebooks/model/deploy_age.prototxt'
'''
age_net = caffe.Classifier(age_net_model_file, age_net_pretrained,
                       mean=mean,
                       channel_swap=(2,1,0),
                       raw_scale=255,
                       image_dims=(256, 256))
'''
age_net = cv2.dnn.readNetFromCaffe(age_net_model_file, age_net_pretrained)

opencv dnn 모듈은 caffe,tensorflow,torch 등의 프레임워크에서 학습된 모델과 ONNX 파일 형식으로 저장된 모델을 불러와 실행할 수 있습니다.

여기서는 opencv를 사용하여 caffe 모델을 로딩하여 age_net 을 생성하기 위해 readNetFromCaffe 를 사용하였습니다.

- Loading the gender network

gender_net_pretrained='/content/drive/MyDrive/Colab Notebooks/model/gender_net.caffemodel'
gender_net_model_file='/content/drive/MyDrive/Colab Notebooks/model/deploy_gender.prototxt'
'''
gender_net = caffe.Classifier(gender_net_model_file, gender_net_pretrained,
                       mean=mean,
                       channel_swap=(2,1,0),
                       raw_scale=255,
                       image_dims=(256, 256))
'''
gender_net = cv2.dnn.readNetFromCaffe(gender_net_model_file, gender_net_pretrained)

6. dlib의 get_frontal_face_detector() 모듈을 이용하여 얼굴인식을 담당하는 detector 생성

detector = dlib.get_frontal_face_detector()

7. 이미지 로딩

- 자신이 알고 싶은 사진의 이미지를 로딩 합니다.

배수지 양의 사진을 테스트 해 보도록 하겠습니다. 사진을 코랩에 업로드 합니다.

img = cv2.imread('./01.jpg')

8. 이미지에서 얼굴의 위치를 찾아서 리스트에 저장

faces = detector(img)

한 사진에 여러명의 얼굴이 있을 수 있는데 각각의 위치들이 리스트에 저장 됩니다.

따라서 이 리스트를 한명씩 뽑아서 위치를 추출하여 이미지에 텍스트로 나이와 성별을 출력해 봅니다.

9. 얼굴 위치에 나이와 성별 출력

for face in faces:
  x1,y1,x2,y2 = face.left(),face.top(),face.right(),face.bottom()
  face_img = img[y1:y2,x1:x2].copy()
  blob = cv2.dnn.blobFromImage(face_img,scalefactor=1,size=(227,227),mean=(78.4263377603,87.7689143744,114.895847746),swapRB=False,crop=False)
  #predict gender
  gender_net.setInput(blob)
  gender_preds = gender_net.forward()
  print(gender_preds[0])
  gender = gender_list[gender_preds[0].argmax()]
  #predict age
  age_net.setInput(blob)
  age_preds = age_net.forward()
  age = age_list[age_preds[0].argmax()]
  # visualize
  cv2.rectangle(img, (x1, y1), (x2, y2), (255, 255, 255), 2)
  overlay_text = '%s %s' % (gender, age)
  cv2.putText(img, overlay_text, org=(x1, y1), fontFace=cv2.FONT_HERSHEY_SIMPLEX,
              fontScale=1, color=(0, 0, 0), thickness=10)
  cv2.putText(img, overlay_text, org=(x1, y1),
              fontFace=cv2.FONT_HERSHEY_SIMPLEX, fontScale=1, color=(255, 255, 255), thickness=2)
  
cv2_imshow(img)
cv2.imwrite('result/01.jpg', img)

설명]

x1,y1,x2,y2 = face.left(),face.top(),face.right(),face.bottom()

얼굴을 찾은 사각형의 왼쪽과 위,오른쪽과 아래를 찾아 x1,y1,x2,y2 값을 저장

face_img = img[y1:y2,x1:x2].copy()

이미지에서 얼굴의 위치만 추출하여 face_img 생성

blob = cv2.dnn.blobFromImage(face_img,scalefactor=1,size=(227,227),mean=(78.4263377603,87.7689143744,114.895847746),swapRB=False,crop=False)


추출된 얼굴부분을 OpenCV 모델이 이해 할 수 있도록 binary 로 변경한다. 뒤에 매개변수는 모델을 설계한 분이 만든 매개변수이므로 값을 그대로 넣어 주면 된다.

  #predict gender
  gender_net.setInput(blob)
  gender_preds = gender_net.forward()
  print(gender_preds[0])
  gender = gender_list[gender_preds[0].argmax()]

 성별을 인식하는 모델에 blob 데이터를 넣어서 gender_preds 저장한다.

여기서 setInput() 은 데이터를 모델에 입력, forward()는 모델을 수행 하는 과정

이 부분이 SoftMax 를 통과하기 때문에 확률이 나오게 되며 gender_preds 에서 argmax() 로 확률이 가장 높은 위치를 가져 오게 된다.

  #predict age
  age_net.setInput(blob)
  age_preds = age_net.forward()
  age = age_list[age_preds[0].argmax()]

나이를 판단하는 모델에 blob 데이터를 넣어서 age_preds 로 꺼내 오고 위와 같은 형식으로 확률이 가장 높은 위치를 가져온다.

  # visualize
  cv2.rectangle(img, (x1, y1), (x2, y2), (255, 255, 255), 2)
  overlay_text = '%s %s' % (gender, age)
  cv2.putText(img, overlay_text, org=(x1, y1), fontFace=cv2.FONT_HERSHEY_SIMPLEX,
              fontScale=1, color=(0, 0, 0), thickness=10)
  cv2.putText(img, overlay_text, org=(x1, y1),
              fontFace=cv2.FONT_HERSHEY_SIMPLEX, fontScale=1, color=(255, 255, 255), thickness=2)

OpenCV를 이용하여 이미지의 사각형 위치에 성별과 나이를 오버레이 시킨다.

cv2_imshow(img)
cv2.imwrite('result/01.jpg', img)

오버레이 시킨 사진을 화면에 출력한 후 result 디렉토리에 파일을 저장해 보자.

사진을 이용하여 사람의 성별과 나이를 대략 유추해 볼 수 있는 모델을 살펴 보았습니다.

자신의 사진을 업로드 해서 정확히 나오는지 판단해 보세요.^^

 

pycharm 을 이용하면 웹캠을 이용하여 지나가는 사람의 성별과 나이를 예측해 볼 수도 있겠네요.^^

 

 

[참고소스]

https://github.com/GilLevi/AgeGenderDeepLearning

 

GitHub - GilLevi/AgeGenderDeepLearning

Contribute to GilLevi/AgeGenderDeepLearning development by creating an account on GitHub.

github.com

https://github.com/kairess/age_gender_estimation

 

GitHub - kairess/age_gender_estimation

Contribute to kairess/age_gender_estimation development by creating an account on GitHub.

github.com

 

사업자 정보 표시
원당컴퓨터학원 | 기희경 | 인천 서구 당하동 1028-2 장원프라자 502호 | 사업자 등록번호 : 301-96-83080 | TEL : 032-565-5497 | Mail : icon001@naver.com | 통신판매신고번호 : 호 | 사이버몰의 이용약관 바로가기