카테고리 없음

[AI] colab, face_landmark, face_type model making

_JIONE_ 2023. 11. 21. 15:50

코랩(colab)이란?

 

웹 브라우저에서 텍스트와 프로그램 코드를 자유롭게 작성할 수 있는 온라인 에디터로, 클라우드 기반의 주피터 노트북 환경을 사용한다. 코랩에서 사용하는 프로그래밍 언어는 파이썬이며, 코랩에서 실행할 수 있는 최소단위는 이다.

 

우선 [파일] - [새 노트]를 클릭하여 face_landmark.ipynb를 생성해보자. 해당 노트는 자동으로 구글드라이브의 [내 드라이브] - [Colab Notebooks] 폴더에 저장된다. 

 

face_landmark 모델이란?

 

"face_landmark"는 주로 얼굴에서 특정 지점(눈, 코, 입의 위치) 들을 찾아내는 기술로, 주로 얼굴 인식 및 분석, 감정 인식, 안면 인증, 메이크업 및 헤어 스타일 추천, 3D 얼굴 모델링 등 다양한 응용 분야에서 사용된다. 또한, 사진이나 비디오에서 얼굴의 움직임을 추적하거나 실시간으로 랜드마크를 감지하여 얼굴에 다양한 효과를 적용하는데에도 활용될 수 있다.

face_landmark를 구현하기 위해서는 딥러닝과 컴퓨터 비전 기술을 사용하는데, 대표적으로 dlib, OpenCV, TensorFlow, PyTorch 등이 사용된다. 

 


 

 

이제 face_landmark 모델 코드를 살펴보자.

 

1. 필요한 패키지 설치

!pip install --upgrade imutils

 

결과: Requirement already satisfied: imutils in /usr/local/lib/python3.10/dist-packages (0.5.4)

 

2. zip file 다운로드

!wget https://pyimagesearch-code-downloads.s3-us-west-2.amazonaws.com/facial-landmarks/facial-landmarks.zip
!unzip -qq facial-landmarks.zip
%cd facial-landmarks

 

결과: --2023-11-21 05:13:31-- https://pyimagesearch-code-downloads.s3-us-west-2.amazonaws.com/facial-landmarks/facial-landmarks.zip Resolving pyimagesearch-code-downloads.s3-us-west-2.amazonaws.com (pyimagesearch-code-downloads.s3-us-west-2.amazonaws.com)... 52.92.149.18, 3.5.84.102, 52.92.144.186, ... Connecting to pyimagesearch-code-downloads.s3-us-west-2.amazonaws.com (pyimagesearch-code-downloads.s3-us-west-2.amazonaws.com)|52.92.149.18|:443... connected. HTTP request sent, awaiting response... 200 OK Length: 74572347 (71M) [binary/octet-stream] Saving to: ‘facial-landmarks.zip’ facial-landmarks.zi 100%[===================>] 71.12M 25.1MB/s in 2.8s 2023-11-21 05:13:34 (25.1 MB/s) - ‘facial-landmarks.zip’ saved [74572347/74572347] /content/facial-landmarks

 

 

3. 필요한 패키지 설치

# import the necessary packages
from matplotlib import pyplot as plt
from imutils import face_utils
import numpy as np
import argparse
import imutils
import dlib
import cv2

 

 

4. Jupyter Notebooks 및 Google Colab에서 이미지를 보여주는 함수 생성

def plt_imshow(title, image):
  # convert the image frame BGR to RGB color space and display it
	image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
	plt.imshow(image)
	plt.title(title)
	plt.grid(False)
	plt.show()

 

 

5. Python에서 dlib 및 OpenCV를 사용하여 얼굴 특징점 찾기

# construct the argument parser and parse the arguments
# ap = argparse.ArgumentParser()
# ap.add_argument("-p", "--shape-predictor", required=True,
# help="path to facial landmark predictor")
# ap.add_argument("-i", "--image", required=True,
# help="path to input image")
# args = vars(ap.parse_args())

# since we are using Jupyter Notebooks we can replace our argument
# parsing code with *hard coded* arguments and values
args = {
	"shape_predictor": "shape_predictor_68_face_landmarks.dat",
	"image": "images/example_01.jpg"
}
  1. "shape_predictor": "shape_predictor_68_face_landmarks.dat": 이 부분은 얼굴 특징점 예측 모델 파일의 경로를 나타낸다. 특징점 예측 모델은 dlib에서 제공한 미리 훈련된 모델로, 얼굴에서 68개의 특징점을 찾는 데 사용된다.
  2. "image": "images/example_01.jpg": 이 부분은 입력 이미지 파일의 경로를 나타낸다. 스크립트는 이 이미지에서 얼굴을 검출하고 얼굴 주변에 사각형을 그리며, 각 얼굴에 대한 특징점을 표시한다.
# initialize dlib's face detector (HOG-based) and then create
# the facial landmark predictor
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor(args["shape_predictor"])

# load the input image, resize it, and convert it to grayscale
image = cv2.imread(args["image"])
image = imutils.resize(image, width=500)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# detect faces in the grayscale image
rects = detector(gray, 1)

   

 1) 얼굴 검출기 및 특징점 예측 모델 초기화:

  • detector = dlib.get_frontal_face_detector(): HOG(Histogram of Oriented Gradients) 기반의 얼굴 검출기를 초기화하여 이미지에서 얼굴을 검출하는 데 사용된다.
  • predictor = dlib.shape_predictor(args["shape_predictor"]): 얼굴 특징점을 예측하는 모델을 초기화한다.

 2) 이미지 로드 및 전처리:

  • image = cv2.imread(args["image"]): 지정된 이미지 파일 경로에서 이미지를 로드한다.
  • image = imutils.resize(image, width=500): 이미지의 너비를 500픽셀로 조정하여 처리 속도를 향상시키고 메모리 사용을 줄이는 데 도움을 준다.
  • gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY): 이미지를 그레이스케일로 변환하여 얼굴 검출 및 특징점 예측 작업은 그레이스케일 이미지에서 수행한다.

  3) 얼굴 검출:

  • rects = detector(gray, 1): 그레이스케일 이미지에서 얼굴을 검출하고 얼굴의 경계 상자 좌표를 반환한다. 1은 이미지를 업샘플링하는 횟수를 나타낸다. 업샘플링은 얼굴이 작아 보일 때 검출 성능을 향상시킬 수 있다.
# loop over the face detections
for (i, rect) in enumerate(rects):
	# determine the facial landmarks for the face region, then
	# convert the facial landmark (x, y)-coordinates to a NumPy
	# array
	shape = predictor(gray, rect)
	shape = face_utils.shape_to_np(shape)

	# convert dlib's rectangle to a OpenCV-style bounding box
	# [i.e., (x, y, w, h)], then draw the face bounding box
	(x, y, w, h) = face_utils.rect_to_bb(rect)
	cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)

	# show the face number
	cv2.putText(image, "Face #{}".format(i + 1), (x - 10, y - 10),
		cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)

	# loop over the (x, y)-coordinates for the facial landmarks
	# and draw them on the image
	for (x, y) in shape:
		cv2.circle(image, (x, y), 1, (0, 0, 255), -1)

# show the output image with the face detections + facial landmarks
plt_imshow("Output", image)

 

  1) 얼굴 검출 반복:

  • for (i, rect) in enumerate(rects):: rects는 얼굴 검출기에서 반환한 얼굴의 경계 상자 좌표로, 이를 반복하면서 각 얼굴에 대한 작업을 수행한다.

  2) 얼굴 특징점 예측 및 시각화:

  • shape = predictor(gray, rect): 현재 얼굴에 대한 특징점을 예측한다. shape는 dlib의 full_object_detection 객체이다.
  • shape = face_utils.shape_to_np(shape): shape_to_np 함수를 사용하여 dlib의 특징점 객체를 NumPy 배열로 변환한다.
  • (x, y, w, h) = face_utils.rect_to_bb(rect): dlib의 rectangle 객체를 OpenCV 스타일의 바운딩 박스로 변환한다. 이 바운딩 박스는 얼굴 주변에 그려진다.
  • cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2): 얼굴 주변에 그려진 바운딩 박스를 이미지에 추가한다.
  • cv2.putText(image, "Face #{}".format(i + 1), (x - 10, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2): 얼굴 번호를 표시하는 텍스트를 이미지에 추가한다.
  • for (x, y) in shape: cv2.circle(image, (x, y), 1, (0, 0, 255), -1): 얼굴의 각 특징점에 대해 빨간색 원을 그려서 시각적으로 나타낸다.

  3) 결과 이미지 표시:

  • plt_imshow("Output", image): 최종 결과 이미지를 표시한다. 이 이미지에는 얼굴 검출 및 특징점이 시각적으로 나타난다.

결과:

 

이로써 face_landmark 모델 코드를 살펴보았다.

 


 

이제 위의 코드를 활용하여 얼굴형  ['Heart', 'Oblong', 'Oval', 'Round', 'Square'] 을 판단하고 몇 %로 일치하는지 출력하는 코드를 짜보자. 

 

첫 번째 방법으로, 아래 블로그처럼 직접 이미지를 모아 학습시킨 뒤에 결과물을 뽑아내는 방법이 있다.

 

Deep Learning - 얼굴형 분류 모델: 모델 정의

Deep Learning 시리즈 시작 - 모델 정의하기

velog.io

 

하지만 우리는 프로젝트를 무사히 끝내는 것이 더 중요했기에 우선!은 더 쉬운 방법을 택했다.
바로 이미지를 올렸을 때, 얼굴 비율에 따라 얼굴형을 분류하는 것인데 따로 이미지 학습이 필요하지 않다.

얼굴형의 비율은 아래 논문을 활용하여 임의로 정하였다.

 

얼굴 형태별 웨이브스타일의 헤어길이에 따른 이미지 지각과 만족도 연구 | DBpia

박종옥 | 서경대학교 | 2013

www.dbpia.co.kr

 

6. 얼굴형 분석 및 결과 HTML 문서를 구글 드라이브에 저장

코랩은 시간이 지나면 결과가 사라지기 때문에 구글 드라이브와 연동하여 결과값을 영구적으로 보관하게 했다.

# 더 세분화된 얼굴형 라벨 정의
labels = {'Heart': (0.7, 1.3), 'Oblong': (1.3, float('inf')), 'Oval': (0.9, 1.1), 'Round': (0.7, 0.9), 'Square': (1.1, 1.3)}

# 얼굴형별 정확도 저장을 위한 딕셔너리
accuracy_dict = {label: 0 for label in labels}

# loop over the face detections
for (i, rect) in enumerate(rects):
    # determine the facial landmarks for the face region, then
    # convert the facial landmark (x, y)-coordinates to a NumPy
    # array
    shape = predictor(gray, rect)
    shape = face_utils.shape_to_np(shape)

    # convert dlib's rectangle to an OpenCV-style bounding box
    # [i.e., (x, y, w, h)], then draw the face bounding box
    (x, y, w, h) = face_utils.rect_to_bb(rect)
    cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)

    # show the face number
    cv2.putText(image, "Face #{}".format(i + 1), (x - 10, y - 10),
                cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)

    # loop over the (x, y)-coordinates for the facial landmarks
    # and draw them on the image
    for (x, y) in shape:
        cv2.circle(image, (x, y), 1, (0, 0, 255), -1)

    # 얼굴형 판별
    face_width = w
    face_height = h
    face_ratio = face_width / face_height

    # 각 얼굴에 대한 얼굴형 판별
    for label, (lower_bound, upper_bound) in labels.items():
        if lower_bound <= face_ratio <= upper_bound:
            accuracy_dict[label] += 1
            break

# 얼굴형별 정확도 출력
total_faces = len(rects)
max_accuracy_label = max(accuracy_dict, key=accuracy_dict.get)
min_accuracy_label = min(accuracy_dict, key=accuracy_dict.get)
max_accuracy_percentage = (accuracy_dict[max_accuracy_label] / total_faces) * 100
min_accuracy_percentage = (accuracy_dict[min_accuracy_label] / total_faces) * 100

for label, count in accuracy_dict.items():
    accuracy_percentage = (count / total_faces) * 100
    print(f"{label} - Accuracy: {accuracy_percentage:.2f}%")

# 가장 부합하는 얼굴형과 부합하지 않는 얼굴형의 정확도 차이 출력
print(f"\nMost Suitable Face Type: {max_accuracy_label} - Accuracy: {max_accuracy_percentage:.2f}%")
print(f"Least Suitable Face Type: {min_accuracy_label} - Accuracy: {min_accuracy_percentage:.2f}%")

from google.colab import drive

# Google Drive 마운트
drive.mount('/content/drive')

# HTML 문서 생성
html_content = f"""
<!DOCTYPE html>
<html>
<head>
    <title>Face Type Analysis Report</title>
</head>
<body>
    <h1>Face Type Analysis Report</h1>
"""

# 얼굴형별 정확도 출력
for label, count in accuracy_dict.items():
    accuracy_percentage = (count / total_faces) * 100
    html_content += f"<p>{label} - Accuracy: {accuracy_percentage:.2f}%</p>"

# 가장 맞는 얼굴형과 부합하지 않는 얼굴형의 정확도 출력
html_content += f"""
    <h2>Most Suitable and Least Suitable Face Types</h2>
    <p>Most Suitable Face Type: {max_accuracy_label} - Accuracy: {accuracy_dict[max_accuracy_label] / total_faces * 100:.2f}%</p>
    <p>Least Suitable Face Type: {min_accuracy_label} - Accuracy: {accuracy_dict[min_accuracy_label] / total_faces * 100:.2f}%</p>
</body>
</html>
"""

# HTML 파일을 Google Drive에 저장
output_path = '/content/drive/MyDrive/face_type_analysis_report.html'
with open(output_path, 'w') as html_file:
    html_file.write(html_content)

# HTML 파일의 경로 출력
print(f"HTML 파일이 생성되었습니다. 경로: {output_path}")

 

결과: 

Heart - Accuracy: 100.00%

Oblong - Accuracy: 0.00%

Oval - Accuracy: 0.00%

Round - Accuracy: 0.00%

Square - Accuracy: 0.00%

Most Suitable Face Type: Heart - Accuracy: 100.00%

Least Suitable Face Type: Oblong - Accuracy: 0.00%

Drive already mounted at /content/drive; to attempt to forcibly remount, call drive.mount("/content/drive", force_remount=True). HTML 파일이 생성되었습니다.

경로: /content/drive/MyDrive/face_type_analysis_report.html

 

구글 드라이브

 

 


 

읽어주셔서 감사합니다.