2017-10-12 54 views
1

我想使用由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) 

sample image of cropped face showing the issue

+0

我不是完全确定你做错了什么,是不是只应该检测这些点? [源](http://www.codesofinterest.com/2017/04/extracting-individual-facial-features-dlib.html) – GPPK

回答

0

它,因为您提供的脸形不是凸的。 fillConvexPoly完全适用于凸形状,在这种情况下,有一个凹角(点#27),因此结果会混乱。

为了解决这个问题,修改功能

def face_remap(shape): 
    remapped_image = cv2.convexHull(shape) 
    return remapped_image 

这将会给你一个结果,它看起来像。 enter image description here

现在你可以多写一些代码(如果你想用那种方式),以去除额头上的三角形截面

+0

辉煌!谢谢,这完美地解决了这个问题!现在你已经提到了,pt#16 - pt#17看起来也是一个凹角,并且fillConvexPoly()可以很好地忍受它。任何想法为什么这样? – Squiggles

+0

在使用dlib来拟合点时总会有一些错误。在点#15-16-17的情况下,它们大多在一条直线上。即使最轻微的错误也可能推动左侧的#16点,使其成为凹角。 解决这个问题需要你在形状中找到一个点的子集,但不是在cv2.convexHull(shape)中。然后他们绕过这些点来覆盖该区域的其余部分。 –