이번 포스팅에서는 저번 포스팅에 이어서 사진을 정면을 보게끔 조정한뒤 얼굴 부분만 잘라내어서 face_recognition 의 성능을 향상시킬수 있는 방법를 정리해보겠다. 다음 코드를 통해 특정 폴더에 위치한 사진들을 불러와서 전처리 해준 다음 새로운 폴더에 저장할수 있게 된다.
import numpy as np
import dlib
import cv2
RIGHT_EYE=list(range(36,42))
LEFT_EYE=list(range(42,48))
EYES=list(range(36,48))
dataset_paths=['./image/tedy-front/','./image/son-front/','./image/unknown-front/']
output_paths=['./image/tedy-align/','./image/son-align/','./image/unknown-align/']
number_images=20
image_type='.jpg'
predictor_file='./model/shape_predictor_68_face_landmarks.dat'
MARGIN_RATIO=1.5
# 마지막에 얻어지는 사진의 size
OUTPUT_SIZE=(96,96)
detector=dlib.get_frontal_face_detector()
predictor=dlib.shape_predictor(predictor_file)
def getFaceDimension(rect):
#얼굴을 가리키는 사각형의 왼쪽 상단 (꼭지점 좌표, 너비, 높이)
return (rect.left(),rect.top(),rect.right()-rect.left(),rect.bottom()-rect.top())
def getCropDimension(rect, center):
width = (rect.right() - rect.left())
half_width = width // 2
(centerX, centerY) = center
startX = centerX - half_width
endX = centerX + half_width
startY = rect.top()
endY = rect.bottom()
return (startX, endX, startY, endY)
for (i,dataset_path) in enumerate(dataset_paths):
# extract the person name from names
output_path=output_paths[i]
for idx in range(number_images):
input_file=dataset_path + str(idx+1) + image_type
# get RGB image from BGR, OpenCV format
image=cv2.imread(input_file)
image_origin=image.copy()
(image_height,image_width) = image.shape[:2]
gray=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
rects=detector(gray,1)
for (i,rect) in enumerate(rects): #검출된 사람의 숫자만큼 반복
(x,y,w,h) = getFaceDimension(rect)
cv2.rectangle(image,(x,y),(x+w,y+h),(0,255,0),2)
points=np.matrix([[p.x,p.y] for p in predictor(gray,rect).parts()]) #68개의 점의 좌표
show_parts=points[EYES] #눈에 해당하는 점
right_eye_center=np.mean(points[RIGHT_EYE],axis=0).astype('int')
left_eye_center=np.mean(points[LEFT_EYE],axis=0).astype('int')
eye_delta_x=right_eye_center[0,0] - left_eye_center[0,0]
eye_delta_y=right_eye_center[0,1] - left_eye_center[0,1]
degree=np.degrees(np.arctan2(eye_delta_y,eye_delta_x)) - 180
eye_distance=np.sqrt((eye_delta_x ** 2) + (eye_delta_y ** 2))
# 사진을 돌린 이후 눈 사이의 거리 조정
aligned_eye_distance=left_eye_center[0,0] - right_eye_center[0,0]
scale=aligned_eye_distance / eye_distance
eyes_center=((left_eye_center[0,0] + right_eye_center[0,0])//2,
(left_eye_center[0,1] + right_eye_center[0,1])//2)
matrix=cv2.getRotationMatrix2D(eyes_center,degree,scale)
wraped=cv2.warpAffine(image_origin,matrix,(image_width,image_height),
flags=cv2.INTER_CUBIC)
(startX,endX,startY,endY) = getCropDimension(rect,eyes_center)
croped=wraped[startY:endY,startX:endX]
output=cv2.resize(croped,OUTPUT_SIZE)
output_file=output_path + str(idx+1) + image_type
cv2.imshow(output_file,output)
cv2.imwrite(output_file,output)
cv2.waitKey(0)
cv2.destroyAllWindows()
'Object Detection' 카테고리의 다른 글
Custom YOLO project - YOLO 이미지 데이터 만들기 (0) | 2021.08.21 |
---|---|
yolov3를 이용한 객체 탐지 (0) | 2021.08.17 |
졸음 감지 프로젝트 (0) | 2021.08.16 |
face alignment (0) | 2021.08.15 |
face_landmark 방법으로 얼굴 검출하기 (0) | 2021.08.15 |