上一篇我们讲了使用OpenCV进行人脸识别的最基础操作。但是从最后的效果可以看出,识别率、效率都很低,而且误检率比较高,识别过程中,系统资源占用相当大,实在是没办法在实际场合中使用。在opencv3.4 版之前自带的人脸检测器是基于Haar算法实现的,不仅检出率低,而且脸的角度稍大一些就检测不出来。但是随着深度学习领域的发展,涌现了一大批效果相当不错的人脸检测算法。
缺点 1)会出现大量的把非人脸预测为人脸的情况; 2)不适用于非正面人脸图像; 3)不抗遮挡。
缺点 基本上没有什么明显的缺点
缺点 1)不能检测小脸,因为它训练数据的最小人脸尺寸为80×80,但是用户可以用较小尺寸的人脸数据自己训练检测器; 2)边界框通常排除前额的一部分甚至下巴的一部分; 3)在严重遮挡下不能很好地工作; 4)不适用于侧面和极端非正面,如俯视或仰视。
缺点 1)CPU速度很慢; 2)不能检测小脸,因为它训练数据的最小人脸尺寸为80×80,但是用户可以用较小尺寸的人脸数据自己训练检测器; 3)人脸包围框甚至小于DLib HoG人脸检测器。
非正面人脸检测效果对比:
通过以上对比,我们可以推荐OpenCV DNN人脸识别作为首选方式
OpenCV提供了两个模型: 1)原始Caffe实现的16位浮点型版本
net = cv2.dnn.readNetFromCaffe("deploy.prototxt", "res10_300x300_ssd_iter_140000_fp16.caffemodel")
2)TensorFlow实现的8位量化版本
net =cv2.dnn.readNetFromTensorflow("opencv_face_detector_uint8.pb", "opencv_face_detector.pbtxt")
OpenCV已经为我们提供了训练好的人脸识别模型,当然我们也可以自己训练,同样可以识别其他物体,实现实物识别。
从上面的模型加载我们看到Caffe需要deploy.prototxt
和res10_300x300_ssd_iter_140000_fp16.caffemodel
两个文件,TensorFlow需要opencv_face_detector_uint8.pb
和opencv_face_detector.pbtxt
两个文件。我查到的很多帖子中都没有详细解释这些文件的来源,好在我找到了,我为大家详细描述一下:
访问目录:opencv/samples/dnn/face_detector
这里有我们需要的deploy.prototxt和opencv_face_detector.pbtxt文件,然后继续GitHub搜索opencv_3rdparty,打开如下:
库是空的,你可能比较懵逼一点,看一下分支
看到如下两个分支,当然还有很多其他的分支是用来做其他检测的,以后用的的可以在里面找,点进去后就能看到我们要下载的模型文件了
image.png
GitHub下载文件就不介绍了,到这里,我们需要的模型文件都下载好了,主要的检测函数有以下四个:
函数原型:def blobFromImage(image, scalefactor=None, size=None, mean=None, swapRB=None, crop=None, ddepth=None)
这个是主要的函数,包含两个过程:
主要参数解释:
(104.0, 177.0, 123.0)
,可能大家对这个比较迷惑,因为它是在模型训练是设定的,我们使用的是已经训练好的模型,直接写死即可。这个在上面图中我圈出的train.prototxt文件中可以看到。
import numpy as np
import cv2, os
def show_detections(image, detections):
h, w, c = image.shape
for i in range(0, detections.shape[2]):
confidence = detections[0, 0, i, 2]
if confidence > 0.6:
box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
(startX, startY, endX, endY) = box.astype("int")
text = "{:.2f}%".format(confidence * 100)
y = startY - 10 if startY - 10 > 10 else startY + 10
cv2.rectangle(image, (startX, startY), (endX, endY),
(0, 255, 0), 1)
cv2.putText(image, text, (startX, y),
cv2.FONT_HERSHEY_SIMPLEX, 0.45, (0, 255, 0), 2)
return image
def detect_img(net, image):
# 其中的固定参数,我们在上面已经解释过了,固定就是如此
blob = cv2.dnn.blobFromImage(image, 1.0, (300, 300), (104.0, 177.0, 123.0), False, False)
net.setInput(blob)
detections = net.forward()
return show_detections(image, detections)
def test_file(net, filepath):
img = cv2.imread(filepath)
showimg = detect_img(net, img)
cv2.imshow("img", showimg)
cv2.waitKey(0)
def test_camera(net):
cap = cv2.VideoCapture('人脸识别.mp4')
while True:
ret, img = cap.read()
if not ret:
break
showimg = detect_img(net, img)
cv2.imshow("img", showimg)
cv2.waitKey(1)
if __name__ == "__main__":
net = cv2.dnn.readNetFromCaffe("deploy.prototxt", "res10_300x300_ssd_iter_140000_fp16.caffemodel")
# net =cv2.dnn.readNetFromTensorflow("opencv_face_detector_uint8.pb", "opencv_face_detector.pbtxt")
# file_path = 'data/380.png'
# test_file(net, file_path)
test_camera(net)
Haar检测结果
Haar检测结果
DNN检测结果
DNN检测结果
以上图片使用Haar无法识别人脸,使用DNN完全可以识别。如果我们使用OpenCV提供的训练模型进行人脸识别,基本上函数调用及参数就是以上的值,而且识别率99%以上。
本文分享自 python爬虫实战之路 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!