OpenCV 人脸检测详解(仅需2行代码学会人脸检测)

简介: 人脸处理是人工智能中的一个热门话题,人脸处理可以使用计算机视觉算法从人脸中自动提取大量信息。在本文中,将通过实战讲解如何使用这些库进行人脸检测,为进一步进行相关处理奠定基础。

人脸检测简介

人脸检测是确定图像中人脸的位置和大小的任务,通常是构建人脸处理应用程序(例如,表情识别、睡意检测、性别分类、人脸识别或人机交互等)的基础,这是由于此类应用程序需要将检测到的人脸位置和大小作为输入。因此,自动人脸检测起着至关重要的作用,是人工智能学科研究最多的课题之一。

人脸检测对人类而言并不困难,但对计算机来说通常涉及许多挑战(例如外观变化、比例变换、旋转、面部表情变换、遮挡或光照条件等)。在本节中,我们将利用 OpenCV 提供的流行人脸检测技术(包括机器学习和深度学习方法)检测图像中的人脸。

使用 OpenCV 进行人脸检测

OpenCV 提供了两种人脸检测方法,包括:

- 基于 Haar 级联的人脸检测器

- 基于深度学习的人脸检测器

基于 Haar 级联的人脸检测器

OpenCV 中提供了基于 Viola 和 Jones 提出对象检测框架的人脸检测算法。此外,该对象检测框架还可用于检测其他物体,例如:车牌号或猫脸等。在本节中,我们将使用此框架检测人脸。

OpenCV 提供了 4 个级联分类器用于人脸检测,可以从 OpenCV 官方下载这些级联分类器文件:

- haarcascade_frontalface_alt.xml (FA1)

- haarcascade_frontalface_alt2.xml (FA2)

- haarcascade_frontalface_alt_tree.xml (FAT)

- haarcascade_frontalface_default.xml (FD)

可以使用不同的数据集评估这些级联分类器的性能,总的来说这些分类器具有相似的准确率,因此,接下来为了简化程序,我们仅使用其中的两个(更具体地说,仅加载级联分类器 FA2 和 FD),大家也可以选择其它感兴趣的分类器测试其性能。

OpenCV 提供了 cv2.CascadeClassifier() 函数用于从文件中加载分类器:

# 加载级联分类器# 第一行代码cas_alt2=cv2.CascadeClassifier("haarcascade_frontalface_alt2.xml")
cas_default=cv2.CascadeClassifier("haarcascade_frontalface_default.xml")

接下来,就可以使用 cv2.CascadeClassifier.detectMultiScale() 函数执行检测了:

# 第二行代码,人脸检测就这么简单faces_alt2=cas_alt2.detectMultiScale(gray)
faces_default=cas_default.detectMultiScale(gray)

cv2.CascadeClassifier.detectMultiScale() 函数检测对象并将它们作为矩形列表返回。为了进行可视化,最后编写 show_detection() 函数进行可视化:

defshow_detection(image, faces):
"""在每个检测到的人脸上绘制一个矩形进行标示"""for (x, y, w, h) infaces:
cv2.rectangle(image, (x, y), (x+w, y+h), (255, 0, 0), 5)
returnimage# 调用 show_detection() 函数标示检测到的人脸img_faces_alt2=show_detection(img.copy(), faces_alt2)
img_faces_default=show_detection(img.copy(), faces_default)

什么,两行代码还觉得麻烦,那么是时候用一行调用检测器并检测人脸了,这就是 OpenCV 提供的 cv2.face.getFacesHAAR() 函数:

# 一行代码实现基于 Haar 级联的人脸检测器,学一送一retval, faces_haar_alt2=cv2.face.getFacesHAAR(img, "haarcascade_frontalface_alt2.xml")
retval, faces_haar_default=cv2.face.getFacesHAAR(img, "haarcascade_frontalface_default.xml")

cv2.CascadeClassifier.detectMultiScale() 需要灰度图像作为输入,而 cv2.face.getFacesHAAR() 需要 BGR 图像作为输入。此外, cv2.CascadeClassifier.detectMultiScale() 将检测到的人脸输出为矩形列表,例如,如果检测到两个人脸,则输出形式如下:

[[809 494152152] [168 503188188]]

而 cv2.face.getFacesHAAR() 函数则以以下格式返回检测到的人脸:

[[[ 809493151151]] [[ 167503189189]]]

因此,如果使用 cv2.face.getFacesHAAR() 函数进行检测,绘制检测框时要调用 np.squeeze() 函数消除多余维度:

faces_haar_alt2=np.squeeze(faces_haar_alt2)
faces_haar_default=np.squeeze(faces_haar_default)

从加载的图像,到检测和绘制人脸的完整代码如下:

# 可视化函数defshow_img_with_matplotlib(color_img, title, pos):
img_RGB=color_img[:, :, ::-1]
ax=plt.subplot(2, 2, pos)
plt.imshow(img_RGB)
plt.title(title, fontsize=8)
plt.axis('off')
# 加载图像img=cv2.imread("test_face_detection.jpg")
# 将 BGR 图像转换为灰度图像gray=cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 加载分类器cas_alt2=cv2.CascadeClassifier("haarcascade_frontalface_alt2.xml")
cas_default=cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
# 检测人脸faces_alt2=cas_alt2.detectMultiScale(gray)
faces_default=cas_default.detectMultiScale(gray)
retval, faces_haar_alt2=cv2.face.getFacesHAAR(img, "haarcascade_frontalface_alt2.xml")
faces_haar_alt2=np.squeeze(faces_haar_alt2)
retval, faces_haar_default=cv2.face.getFacesHAAR(img, "haarcascade_frontalface_default.xml")
faces_haar_default=np.squeeze(faces_haar_default)
# 绘制人脸检测框img_faces_alt2=show_detection(img.copy(), faces_alt2)
img_faces_default=show_detection(img.copy(), faces_default)
img_faces_haar_alt2=show_detection(img.copy(), faces_haar_alt2)
img_faces_haar_default=show_detection(img.copy(), faces_haar_default)
# 可视化show_img_with_matplotlib(img_faces_alt2, "detectMultiScale(frontalface_alt2): "+str(len(faces_alt2)), 1)
show_img_with_matplotlib(img_faces_default, "detectMultiScale(frontalface_default): "+str(len(faces_default)), 2)
show_img_with_matplotlib(img_faces_haar_alt2, "getFacesHAAR(frontalface_alt2): "+str(len(faces_haar_alt2)), 3)
show_img_with_matplotlib(img_faces_haar_default, "getFacesHAAR(frontalface_default): "+str(len(faces_haar_default)), 4)
plt.show()

程序的输出如下图所示:

绘图190.png

如上图所示,通过使用基于 haar 特征的不同级联分类器检测到的人脸会有所不同。最后,还需要说明的是,cv2.CascadeClassifier.detectMultiScale() 函数有 minSize 和 maxSize 参数,用以设置最小尺寸(小于 minSize 的对象将不被检测)和最大尺寸(大于 maxSize 的对象将不被检测到),而 cv2.face.getFacesHAAR() 函数并不提供此参数。

基于深度学习的人脸检测器

除了基于 Haar 级联的人脸检测器外,OpenCV 提供了基于深度学习的人脸检测器,OpenCV 深度神经网络 (Deep Neural Networks, DNN) 人脸检测器基于使用 ResNet-10 网络的 Single Shot MultiBox Detector (SSD) 框架。

OpenCV 中 DNN 模块,使用流行的深度学习框架(例如 Caffe、TensorFlow、Torch 和 Darknet )通过预先训练的深度网络实现前向计算(即推理阶段)。这意味着我们可以使用预训练的网络执行完整的前向计算并利用输出在我们的应用程序中进行预测,而不需要花费数小时来训练网络。

接下来,我们预训练的深度学习人脸检测器模型执行人脸检测,使用以下两种模型:

- 人脸检测器 (FP16):Caffe 实现的浮点 16 版本,为了使用此检测器,首先下载模型文件(deploy.prototxt)和配置文件(res10_300x300_ssd_iter_140000_fp16.caffemodel);

- 人脸检测器 (UINT8):TensorFlow 实现的 8 位量化版本,为了使用此检测器,首先下载模型文件(opencv_face_detector.pbtxt)和配置文件(opencv_face_detector_uint8.pb)。

接下来介绍如何使用预训练的深度学习人脸检测器模型来检测人脸,第一步同样是是加载预训练的模型:

# 加载预训练的模型, Caffe 实现的版本net=cv2.dnn.readNetFromCaffe("deploy.prototxt", "res10_300x300_ssd_iter_140000_fp16.caffemodel")
# 加载预训练的模型, Tensorflow 实现的版本# net = cv2.dnn.readNetFromTensorflow("opencv_face_detector_uint8.pb", "opencv_face_detector.pbtxt")

为了获得最佳精度,必须分别对蓝色、绿色和红色通道执行 (104, 177, 123) 通道均值减法,并将图像调整为 300 x 300 的 BGR 图像,在 OpenCV 中可以通过使用 cv2.dnn.blobFromImage() 函数进行此预处理:

blob=cv2.dnn.blobFromImage(image, 1.0, (300, 300), [104., 117., 123.], False, False)

下一步是将 blob 设置为输入以获得结果,对整个网络执行前向计算以计算输出:

# 将 blob 设置为输入并获取检测结果net.setInput(blob)
detections=net.forward()

最后一步是迭代检测并绘制结果,仅在相应置信度大于最小阈值时才将其可视化:

# 迭代所有检测结果foriinrange(0, detections.shape[2]):
# 获取当前检测结果的置信度confidence=detections[0, 0, i, 2]
# 如果置信大于最小置信度,则将其可视化ifconfidence>0.7:
detected_faces+=1# 获取当前检测结果的坐标box=detections[0, 0, i, 3:7] *np.array([w, h, w, h])
        (startX, startY, endX, endY) =box.astype('int')
# 绘制检测结果和置信度text="{:.3f}%".format(confidence*100)
y=startY-10ifstartY-10>10elsestartY+10cv2.rectangle(image, (startX, startY), (endX, endY), (255, 0, 0), 3)
cv2.putText(image, text, (startX, y), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 0, 255), 2)
# 可视化show_img_with_matplotlib(image, "DNN face detector: "+str(detected_faces), 1)
plt.show()

基于深度学习的人脸检测器的检测结果如下所示:

绘图191.png

从上图中可以看出,三个正面人脸都可以被两个深度学习模型高置信度地检测到。

相关文章
|
7月前
|
算法 IDE 开发工具
OpenCV常用的 7 个示例:从读取到人脸检测(Python版)
OpenCV常用的 7 个示例:从读取到人脸检测(Python版)
|
计算机视觉 C++ Python
OpenCV人脸检测打卡系统
OpenCV人脸检测打卡系统
98 0
|
6月前
|
机器学习/深度学习 Java 开发工具
【移花接木】OpenCV4.8 For Java 深度学习 实时人脸检测
【移花接木】OpenCV4.8 For Java 深度学习 实时人脸检测
106 0
|
7月前
|
XML 算法 计算机视觉
使用OpenCV进行人脸检测和戴墨镜特效实战(附Python源码)
使用OpenCV进行人脸检测和戴墨镜特效实战(附Python源码)
313 1
|
6月前
|
监控 安全 计算机视觉
实战 | 18行代码轻松实现人脸实时检测【附完整代码与源码详解】Opencv、人脸检测
实战 | 18行代码轻松实现人脸实时检测【附完整代码与源码详解】Opencv、人脸检测
|
6月前
|
机器学习/深度学习 算法 数据可视化
基于OpenCV的人脸检测软件(含Python源码+UI界面+图文详解)
基于OpenCV的人脸检测软件(含Python源码+UI界面+图文详解)
|
7月前
|
前端开发 Java Maven
java集成opencv(不踩坑),实现人脸检测小demo(含上传人像图片识别接口),windows,IDEA,Springboot
java集成opencv(不踩坑),实现人脸检测小demo(含上传人像图片识别接口),windows,IDEA,Springboot
1075 0
|
编解码 计算机视觉 Ruby
Python图像处理(二)opencv人脸检测
人脸检测部分,我们需要使用到opencv,看清楚,是opencv,不是opencv_python 首先,我们打开opencv的官网:opencv.org/# 当然,纯英文的。 我们找到library目录下的release目录: 选择你需要的版本,下载对应的平台就好。如下图所示,我当然要尝试最新版的了。 下载完成之后,双击安装就可以了。 我理解的人脸检测呢,其实就是opencv根据采集到的图像与其库中预置的人脸特征去比对,有符合人脸特征的,就说明采集到的图像是有人脸的。初学,我也不清楚我说的是否正确。 有不对的地方,欢迎大佬指出。
76 0
|
文字识别 算法 IDE
OpenCV常用的 7 个示例:从读取到人脸检测(Python版)
OpenCV常用的 7 个示例:从读取到人脸检测(Python版)
|
机器学习/深度学习 数据可视化 计算机视觉
人脸检测实战高级:使用 OpenCV、Python 和 dlib 完成眨眼检测
今天,我们使用面部标记和 OpenCV 检测视频流中的眨眼次数。 为了构建我们的眨眼检测器,我们将计算一个称为眼睛纵横比 (EAR) 的指标,该指标由 Soukupová 和 Čech 在他们 2016 年的论文《使用面部标记的实时眨眼检测》中介绍。
446 0
人脸检测实战高级:使用 OpenCV、Python 和 dlib 完成眨眼检测