18

7行代码(OpenCV)的人脸识别

看了《7行Python的人脸识别》一文后,简单尝试了一下,发现识别准确度不够。原始图像如下:

图片描述

识别后的结果:

图片描述

把酒杯识别成了人脸,而该是人脸的又没有识别出来,还多余识别了一条裤子。

检查代码,最关键是第2条语句:

face_patterns = cv2.CascadeClassifier('/usr/local/opt/opencv/share/OpenCV/haarcascades/haarcascade_frontalface_default.xml')

我们检查/usr/local/opt/opencv/share/OpenCV这个目录,发现它下面的内容是这样的:

图片描述

下面有2个子目录,分别是haarcascadeslbpcascades,这里面还包括了眼睛识别,鼻子识别,嘴巴识别等等,甚至还有猫脸识别,此外,光人脸识别就有好几种:frontalface_default, frontalface_alt, frontalface_alt2, frontalface_alt_tree等等,你可以挨个试一下(我试的结果是哪个也不准确)。实际上就是OpenCV通过Haar特征和LBP特征预置了一些事先做好的结果以方便用户调用。关于这些特征是如何提取的,可以参见《图像特征提取三大法宝:HOG特征,LBP特征,Haar特征》。

那我们把第2条语句换成LBP试一下呢?

face_patterns = cv2.CascadeClassifier('/usr/local/opt/opencv/share/OpenCV/lbpcascades/lbpcascade_frontalface.xml')

结果也并不理想,不是没有把人脸识别出来,就是把杯子识别成了人脸,不是多了就是少了,总是不能正确识别所有人脸。

10行代码(dlib)的人脸识别

那么有没有办法提高人脸识别的准确度呢?无意中发现了dlib这个神器,它实现了一篇大牛论文《One Millisecond Face Alignment with an Ensemble of Regression Trees》里的算法,论文标题就叫《用集成回归树实现一毫秒的人脸识别》,可见作者的自信。

膜拜完大神,直接开干!首先,安装dlib以及相关依赖工具:

brew install boost
brew install boost-python
pip install dlib
pip install scikit-image

代码略作改动:

import dlib
from skimage import io
from skimage.draw import polygon_perimeter

detector = dlib.get_frontal_face_detector()
sample_image = io.imread('/Users/zhangjing/Desktop/IMG_5528.jpg')
faces = detector(sample_image, 1)

for d in faces:
    rr, cc = polygon_perimeter([d.top(), d.top(), d.bottom(), d.bottom()], [d.right(), d.left(), d.left(), d.right()])
    sample_image[rr, cc] = (0, 255, 0)
io.imsave('/Users/zhangjing/Desktop/IMG_5528_detected_dlib.jpg', sample_image)

执行之后效果是这样的:

图片描述

完美识别!

结论:如果要做人脸识别的话,建议选择dlib,而不要选择OpenCV。


张京
13.4k 声望4.7k 粉丝

现任北京联云天下科技有限公司技术副总裁。1994年毕业于清华大学计算机科学与技术专业;20多年软件开发及项目管理经验;历任亚洲生活网络公司CTO,摩托罗拉软件中心QSE工具经理,融信恒通技术总监,安必信软件公...