使用 dlib 对人脸特征点标记

我在做表情识别的时候,使用的是 CK/CK+ 的数据集,然而令人难受的是,我一直不知道如何去标记人脸特征点。因为数据集里面有标记好的 Landmarks,都放在里面了。所以我训练是直接用这个数据的,测试集其实也是从里面随机抽取的。

然而昨天在找资料的时候,我很敏感的发现了68这个数字。天哪,我怎么会忘记,这个就是 CK/CK+ 数据集里面标记点的个数啊!

于是,我开始了 dlib 的调试。


配置

话不多说,还是:

macOS + anaconda + Python2.7

dlib 的安装:

对于 Mac 用户,参见这一篇

其实我根本就是忘记了我在安装 face_recognition 时曾经在 Python3 的环境下安装过 dlib 了。看这里

特征检测器

需要下载特征检测器,当然你也可以自己训练 (/滑稽)

下载后可以解压出一个 dat 文件,我们需要的就是这个。


检测人脸

之前就说过,dlib 也是可以检测人脸的。

1
2
detector = dlib.get_frontal_face_detector()
faces = detector(img, 1)

这样,faces 里面就存储了所有脸部区域的范围。

值得注意的是,faces[i] 是第 i 张脸,使用.top() .bottom() .left() .right()四个函数得到具体的值


特征点标记

加载刚刚下载的文件来标记特征点。

1
2
landmark_predictor = dlib.shape_predictor('./shape_predictor_68_face_landmarks.dat')
shape = landmark_predictor(img,face_area)

其中,shape 就保存了特征点的信息。

为了得到特征点的坐标,需要使用.part()函数,如下:

1
2
x[i] = shape.part(i).x
y[i] = shape.part(i).y

特征点是有顺序的,如下图:

68个特征点的位置如下:

1
2
3
4
5
6
7
8
9
10
{
IdxRange jaw; // [0 , 16]
IdxRange rightBrow; // [17, 21]
IdxRange leftBrow; // [22, 26]
IdxRange nose; // [27, 35]
IdxRange rightEye; // [36, 41]
IdxRange leftEye; // [42, 47]
IdxRange mouth; // [48, 59]
IdxRange mouth2; // [60, 67]
}

实战

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# -*- coding:utf-8 -*-

import cv2
import dlib

detector = dlib.get_frontal_face_detector()
landmark_predictor = dlib.shape_predictor('./shape_predictor_68_face_landmarks.dat')
img = cv2.imread('./lyf2.png')
faces = detector(img, 1)

if (len(faces) > 0):
for k,d in enumerate(faces):
# cv2.rectangle(img,(d.left(),d.top()),(d.right(),d.bottom()),(255,255,255))
shape = landmark_predictor(img,d)
for i in range(68):
img2 = cv2.circle(img, (shape.part(i).x, shape.part(i).y),5,(0,255,0), -1, 8)
img2 = cv2.putText(img,str(i),(shape.part(i).x,shape.part(i).y),cv2.FONT_HERSHEY_SIMPLEX,0.5,(255,2555,255))
cv2.imshow('Frame',img)
cv2.imwrite('./landmark.jpg', img2)
cv2.waitKey(0)

效果如下:





,你问 Landmark 还可以用来干嘛?

当然是让美帝也感受一下膜法的力量!!!





根据眼睛眉毛附近的点,来设计黑框眼镜的位置和大小。

代码很简单,我就不放了

0%