OpenCV检测面部特征点(耳-下巴-耳线)

3

我正在寻找一个opencv(Python版本)的函数,用于检测人脸上左耳-下巴-右耳(看起来像抛物线)的线条。是否有任何一种haarcascade可以完成这项工作?我已经知道了正面人脸或眼睛的haarcascades,但我正在寻找更精确的东西。

2个回答

7
你所寻找的是面部关键点检测,可以尝试使用DLIB。DLIB用C++编写,但也有Python包装器。安装说明 现在使用DLIB,你可以实现这个功能。

代码

import cv2
import dlib
import numpy

PREDICTOR_PATH = "/home/zed/dlib/files/shape_predictor_68_face_landmarks.dat"
predictor = dlib.shape_predictor(PREDICTOR_PATH)
cascade_path='haarcascade_frontalface_default.xml'
cascade = cv2.CascadeClassifier(cascade_path)

# #This is using the Dlib Face Detector . Better result more time taking
# def get_landmarks(im):
#     rects = detector(im, 1)
#     rect=rects[0]
#     print type(rect.width())
#     fwd=int(rect.width())
#     if len(rects) == 0:
#         return None,None

#     return np.matrix([[p.x, p.y] for p in predictor(im, rects[0]).parts()]),fwd

def get_landmarks(im):
    rects = cascade.detectMultiScale(im, 1.3,5)
    x,y,w,h =rects[0]
    rect=dlib.rectangle(x,y,x+w,y+h)
    return numpy.matrix([[p.x, p.y] for p in predictor(im, rect).parts()])

def annotate_landmarks(im, landmarks):
    im = im.copy()
    for idx, point in enumerate(landmarks):
        pos = (point[0, 0], point[0, 1])
        cv2.putText(im, str(idx), pos,
                    fontFace=cv2.FONT_HERSHEY_SCRIPT_SIMPLEX,
                    fontScale=0.4,
                    color=(0, 0, 255))
        cv2.circle(im, pos, 3, color=(0, 255, 255))
    return im

im=cv2.imread('face_leo1.jpg')
cv2.imshow('Result',annotate_landmarks(im,get_landmarks(im)))
cv2.waitKey(0)
cv2.destroyAllWindows()

结果

enter image description here

与地标相关的要点:

FACE_POINTS = list(range(17, 68))
MOUTH_POINTS = list(range(48, 61))
RIGHT_BROW_POINTS = list(range(17, 22))
LEFT_BROW_POINTS = list(range(22, 27))
RIGHT_EYE_POINTS = list(range(36, 42))
LEFT_EYE_POINTS = list(range(42, 48))
NOSE_POINTS = list(range(27, 35))
JAW_POINTS = list(range(0, 17))
CHIN_POINTS=list(range(6,11))

然而,在rect=dlib.rectangle(x,y,x+w,y+h)这一行出现了错误,错误信息为Boost.Python.ArgumentError: Python argument types in rectangle.__init__(rectangle, numpy.int32, numpy.int32, numpy.int32, numpy.int32) did not match C++ signature: __init__(_object*, long left, long top, long right, long bottom) __init__(_object*)。你是否已经遇到过这个错误并知道如何修复它? - fonfonx
我没有得到完全像这样的错误,但我遇到了很多问题,并想出了这个解决方案,它起作用了。:/ 你有正确级联路径和预测器吗?? - Arijit
我通过编写 x,y,w,h =rects[0].astype(long) 解决了这个问题。 - fonfonx
现在可以工作了吗?我添加了另一种方法,使用dlib面部检测器而不是Opencv haar级联。 - Arijit
是的,它可以工作。显然,级联给出了int32矩形,而dlib矩形方法(编写为C ++)需要long整数。 - fonfonx

0

还有一个易于使用的dlib包装器,名为face_recognition

from face_recognition import load_image_file, face_locations

# load to numpy array
img_array = load_image_file("img.jpg")

# returns a list with a dict for each face
# each face-dict contains landmarks for features like chin, nose.. etc
landmarks = face_locations(img_array)

img from thispersondoesnotexist.com


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接