使用dlib面部标志裁剪脸部
我想使用由dlib标识的面部标志来裁剪脸部。右眉毛导致问题 - 作物平坦而不是跟随眉毛。使用dlib面部标志裁剪脸部
我在这里做错了什么?
from imutils import face_utils
import imutils
import numpy as np
import collections
import dlib
import cv2
def face_remap(shape):
remapped_image = shape.copy()
# left eye brow
remapped_image[17] = shape[26]
remapped_image[18] = shape[25]
remapped_image[19] = shape[24]
remapped_image[20] = shape[23]
remapped_image[21] = shape[22]
# right eye brow
remapped_image[22] = shape[21]
remapped_image[23] = shape[20]
remapped_image[24] = shape[19]
remapped_image[25] = shape[18]
remapped_image[26] = shape[17]
# neatening
remapped_image[27] = shape[0]
return remapped_image
"""
MAIN CODE STARTS HERE
"""
# load the input image, resize it, and convert it to grayscale
image = cv2.imread("images/faceCM1.jpg")
image = imutils.resize(image, width=500)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
out_face = np.zeros_like(image)
# initialize dlib's face detector (HOG-based) and then create the facial landmark predictor
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor(SHAPE_PREDICTOR)
# detect faces in the grayscale image
rects = detector(gray, 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)
#initialize mask array
remapped_shape = np.zeros_like(shape)
feature_mask = np.zeros((image.shape[0], image.shape[1]))
# we extract the face
remapped_shape = face_remap(shape)
cv2.fillConvexPoly(feature_mask, remapped_shape[0:27], 1)
feature_mask = feature_mask.astype(np.bool)
out_face[feature_mask] = image[feature_mask]
cv2.imshow("mask_inv", out_face)
cv2.imwrite("out_face.png", out_face)
它,因为您提供的脸形不是凸的。 fillConvexPoly完全适用于凸形状,在这种情况下,有一个凹角(点#27),因此结果会混乱。
为了解决这个问题,修改功能
def face_remap(shape):
remapped_image = cv2.convexHull(shape)
return remapped_image
现在你可以多写一些代码(如果你想用那种方式),以去除额头上的三角形截面
辉煌!谢谢,这完美地解决了这个问题!现在你已经提到了,pt#16 - pt#17看起来也是一个凹角,并且fillConvexPoly()可以很好地忍受它。任何想法为什么这样? – Squiggles
在使用dlib来拟合点时总会有一些错误。在点#15-16-17的情况下,它们大多在一条直线上。即使最轻微的错误也可能推动左侧的#16点,使其成为凹角。 解决这个问题需要你在形状中找到一个点的子集,但不是在cv2.convexHull(shape)中。然后他们绕过这些点来覆盖该区域的其余部分。 –
我不是完全确定你做错了什么,是不是只应该检测这些点? [源](http://www.codesofinterest.com/2017/04/extracting-individual-facial-features-dlib.html) – GPPK