본문 바로가기

AI Inventors 개발 Story

AI Inventors History#2-2 "Personalcolor AI 개발 - 얼굴인식과 얼굴 피부 추출" 본문

IT 개발 프로젝트/Personalcolor AI 개발

AI Inventors History#2-2 "Personalcolor AI 개발 - 얼굴인식과 얼굴 피부 추출"

ai.inventors 2020. 8. 14. 23:29

안녕하세요 :)

AI Inventors 입니다.

 

이번 퍼스널컬러AI 개발 3번째 포스팅에서는

퍼스널컬러 분석의 기본 시작점이 되는 얼굴인식과 얼굴 피부 추출 부분을 소개해보겠습니다.

 

※ 이 포스팅의 내용 역시 Python 기본 내용을 포함하고 있지 않으며,

Python 기본 교육이 필요하신 분 께서는 유튜브 등을 참고하셔주시기 바랍니다.

(추후, Python 기초 내용은 포스팅하도록 하겠습니다.)

 

퍼스널컬러 분석은,

개개인의 얼굴 고유의 피부색을 분석하고,

퍼스널컬러의 각 카테고리별 컬러와 얼마나 유사하게 잘 어울리는지를 분석하는 작업입니다.

 

따라서, 각 이미지 데이터에서 피부톤의 색상을 추출해내는 것이 필요합니다.

 

그래서 저희는 다음과 같이

1. 이미지 데이터에서 얼굴을 인식

2. 인식된 얼굴에서 피부 색만을 분리

3. 피부색에서 명도/채도 등 원하는 Feature값을 추출

 

하는 3단계의 방식으로 작업을 진행하였습니다.

 

 

1. 얼굴 인식 알고리즘(OpenCV, Dlib)

 

구글에 "Face detction using OpenCV in python" 등의 검색어로 구글링을 해보면

OpenCV를 활용한 얼굴 인식/눈 인식 등의 아주 다양한 예제들이 등장합니다.

(https://towardsdatascience.com/face-detection-in-2-minutes-using-opencv-python-90f89d7c0f81)

 

 

 

openCV를 활용하여 얼굴인식을 할 수 있도록

xml파일로 Face Detection 라이브러리를 만들어 놓기도 하구요

(아래 코드 참조)

 

faceCascade = cv2.CascadeClassifier('./haarcascade_frontalface_default.xml')
faces = faceCascade.detectMultiScale(frameGray)
for face in faces:
    x1, y1, w, h = face 
    x2 = x1 + w 
    y2 = y1 + h

 

 

또한, 저희가 사용하기도 했던 Dlib 라이브러리의 경우,

Opencv의 Face Casecade 알고리즘보다 인식률 또한 높고, 오인식률도 비교적 낮은편이라

믿고 쓰는 Face Detection 알고리즘이었습니다.

 

코드는 아래 참조하시면 될 것 같구요.

FaceDetector = dlib.get_frontal_face_detector()
face = FaceDetector(image)
for face in faces:
      x1, y1, x2, y2 = face.left(), face.top(), face.right(), face.bottom()

 

Dlib의 경우 Windows Local PC환경이나 Linux 서버 위에서 구동시키려면 

직접 설치를 해주셔야 하는데, 이 설치과정이 매우 번거롭습니다

(물론, Google Colab에는 기본환경으로 탑재되어 있기 때문에, install 없이 바로 쓰셔도 됩니다.)

 

 

 2. 피부색상 추출

 

피부 색상을 추출해 내는 것은 생각만큼 간단한 일은 아닙니다.

Dlib에서 추출한 얼굴인식의 경우, 얼굴 주위로 사각형을 만들어주는 인식 알고리즘이기에,

Dlib에서 생성한 사각형 내부에는 주위 배경색, 얼굴색, 눈 색, 눈썹/머리 모발색 등이 혼합되어 있습니다.

 

이 역시 해결 방법을 찾기위해 구글링을 해보니!!

 

(https://www.researchgate.net/publication/262371199_Explicit_image_detection_using_YCbCr_space_color_model_as_skin_detection)

 

 

위와 같은 논문 하나를 찾을 수 있었습니다.

논문의 내용을 요약해서 말씀드리자면,

YCbCr Color Space내에서 사람의 피부는 (0,133,77) ~ (255,173,127) 영역 내에 존재한다는 내용입니다.

 

따라서, 피부색상 추출 역시 다음과 같이

1. 얼굴 추출 이미지 데이터 RGB → YCbCr 변환

2. YCbCr Colorspace내에서 피부 색상 추출을 위한 마스크 생성

3. 생성된 마스크와 원본 데이터를 결합하여 피부 색상 추출

 

과정을 거쳐 알고리즘을 구현하였습니다.

 

1) RGB → YCbCr 변환

 

YCbCr 변환은 특별하게 수식 변환 과정 없이,

OpenCV 내에 구현되어있는 CVTColor함수를 사용하였습니다.

face_img_ycrcb = cv2.cvtColor(face_img, cv2.COLOR_BGR2YCrCb)

opencv 패키지 내에는 내장함수로 꽤나 많은 컬러변환 함수들이 들어있기에

꽤나 유용하게 사용하실 수 있습니다.

 

2) YCbCr Mask 생성

 

Mask 생성을 위해 피부색상의 하한선이 될 lower array와 상한선이 될 upper array를 생성해줍니다.

이후, opencv의 inRange함수에, 원본이 될 이미지 YCbCr color space와 lower array, upper array를 입력해주면

Mask가 생성됩니다.

lower = np.array([0,133,77], dtype = np.uint8)
upper = np.array([255,173,127], dtype = np.uint8)
skin_msk = cv2.inRange(face_img_ycrcb, lower, upper)

 

OpenCV의 inRange함수는

특정 이미지 데이터의 상/하한선을 정해놓고 그 안에 들어오는 pixel들은 1로,

나머지 pixel들은 0으로 만들겠다 라는 함수 입니다.

 

 

3) 생성한 Mask를 원본 이미지에 입힘

 

역시나 Opencv에는 생성한 Mask와 원본이미지를 결합할 아주 적절한 함수가 있습니다.

바로, bitwise_and 함수인데요.

아래와 같이 작성하여 입력하면,

앞에는 face_img원본이 들어가고, 뒤에는 masking된 face_img가 들어간 채로 

bit단위의 AND 연산을 수행하게 됩니다.

 

따라서, mask가 씌워지지 않은 부분의 픽셀은 날라가고,

mask가 씌워진 부분의 픽셀만 남아있게 됩니다.

skin = cv2.bitwise_and(face_img, face_img, mask = skin_msk)

 

 

 

위의 과정대로 따라오시면,

퍼스널컬러 분석의 기본 토대가 될

얼굴인식과 피부색상 추출 과정을 완료하시게 됩니다.

 

감사합니다.

Have a Nice day~!

AI Inventors.

 

Comments