2017-10-12 84 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)中。然後他們繞過這些點來覆蓋該區域的其餘部分。 –