OpenCV-Python实战(14)——人脸检测详解(仅需6行代码学会4种人脸检测方法)
2026/7/21 15:55:36 网站建设 项目流程

OpenCV-Python实战(14)——人脸检测详解(仅需6行代码学会4种人脸检测方法)

    • 0. 前言
    • 1. 人脸处理简介
    • 2. 安装人脸处理相关库
      • 2.1 安装 dlib
      • 2.2 安装 face_recognition
      • 2.3 安装 cvlib
    • 3. 人脸检测
      • 3.1 使用 OpenCV 进行人脸检测
        • 3.1.1 基于 Haar 级联的人脸检测器
        • 3.1.2 基于深度学习的人脸检测器
      • 3.2 使用 dlib 进行人脸检测
        • 3.2.1 基于 HOG 特征和滑动窗口的人脸检测器
        • 3.2.2 基于 CNN 的人脸检测器
      • 3.3 使用 face_recognition 进行人脸检测
      • 3.4 使用 cvlib 进行人脸检测
    • 小结
    • 系列链接

0. 前言

人脸处理是人工智能中的一个热门话题,人脸处理可以使用计算机视觉算法从人脸中自动提取大量信息,例如身份、意图和情感。人脸在视觉交流中起着重要作用,这是由于人脸中包含大量非语言信息,因此人脸处理一直以来对于计算机视觉学习者来说都是非常有趣的话题,因为它涉及不同的专业领域,例如对象检测、特征点检测以及对象跟踪等。在本文中,将首先介绍常用人脸处理库,然后通过实战讲解如何使用这些库进行人脸检测,为进一步进行相关处理奠定基础。

1. 人脸处理简介

为了专注人脸处理相关主题,我们将使用 OpenCV 库,以及 dlib、face_recognition 和 cvlib 等Python包。同时,本文将在人脸处理中使用不同的方法,以介绍解决具体人脸处理任务的不同方法,对不同方法的介绍将有助于大家根据不同的应用需求选择不同的方法。下图展示了人脸处理的相关主题,以及可用的Python包:


如上图所示,人脸处理主要包括以下主题:

  • 人脸检测:对象检测的一种特殊情况,其任务是找到图像中所有人脸的位置和大小。
  • 面部特征点检测:特征点检测的一种特殊情况,其任务是定位人脸中的主要特征点。
  • 人脸跟踪:对象跟踪的一种特殊情况,其任务是利用在视频的连续帧中提取的额外信息,找到视频中所有移动人脸的位置和大小。
  • 人脸识别:目标识别的一种特殊情况,其任务是使用从人脸中提取的信息从图像或视频中识别或验证一个人:
    • 人脸识别 (1:N):在已知人脸集合中找到与检测到的人脸最接近的匹配项
    • 人脸验证 (1:1):检查检测到的人脸是否是其所声称的人

如上所述,人脸处理主要包括:人脸检测面部特征点检测人脸追踪人脸识别,本文主要关注使用OpenCVdlibface_recognitioncvlib库进行人脸检测,关于其他人脸处理主题将在后续系列中进行介绍。

2. 安装人脸处理相关库

2.1 安装 dlib

Dlib 是一个包含计算机视觉、机器学习和深度学习算法的 C++ 软件库,也可以在Python应用程序中使用,安装dlib,需要使用以下命令:

pipinstalldlib

2.2 安装 face_recognition

face_recognition 是一个强大、简单、易上手的人脸识别开源项目,为了在Python中使用face_recognition库,使用以下命令进行安装:

pipinstallface_recognition

2.3 安装 cvlib

cvlib一个高级、易用、开源的Python计算机视觉库,要安装 cvlib 包,首先需要安装以下依赖库:numpyopencv-pythonrequestsprogressbarpillowtensorflow以及keras
然后,再安装cvlib包:

pipinstallcvlib

3. 人脸检测

人脸检测是确定图像中人脸的位置和大小的任务,通常是构建人脸处理应用程序(例如,表情识别、睡意检测、性别分类、人脸识别或人机交互等)的基础,这是由于此类应用程序需要将检测到的人脸位置和大小作为输入。因此,自动人脸检测起着至关重要的作用,是人工智能学科研究最多的课题之一。
人脸检测对人类而言并不困难,但对计算机来说通常涉及许多挑战(例如外观变化、比例变换、旋转、面部表情变换、遮挡或光照条件等)。在本节中,我们将利用OpenCVdlibface_processing等提供的流行人脸检测技术(包括机器学习和深度学习方法)检测图像中的人脸。

3.1 使用 OpenCV 进行人脸检测

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

  • 基于 Haar 级联的人脸检测器
  • 基于深度学习的人脸检测器
3.1.1 基于 Haar 级联的人脸检测器

OpenCV中提供了基于ViolaJones提出对象检测框架的人脸检测算法。此外,该对象检测框架还可用于检测其他物体,例如:车牌号或猫脸等。在本节中,我们将使用此框架检测人脸。
OpenCV提供了 4 个级联分类器用于人脸检测,可以从OpenCV 官方下载这些级联分类器文件:

  • haarcascade_frontalface_alt.xml (FA1)
  • haarcascade_frontalface_alt2.xml (FA2)
  • haarcascade_frontalface_alt_tree.xml (FAT)
  • haarcascade_frontalface_default.xml (FD)

可以使用不同的数据集评估这些级联分类器的性能,总的来说这些分类器具有相似的准确率,因此,接下来为了简化程序,我们仅使用其中的两个(更具体地说,仅加载级联分类器FA2FD),大家也可以选择其它感兴趣的分类器测试其性能。
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()将检测到的人脸输出为矩形列表,例如,如果检测到两个人脸,则输出形式如下:

[[809494152152][168503188188]]

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()

程序的输出如下图所示:


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

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

除了基于Haar级联的人脸检测器外,OpenCV 提供了基于深度学习的人脸检测器,OpenCV深度神经网络 (Deep Neural Networks,DNN) 人脸检测器基于使用ResNet-10网络的 Single Shot MultiBox Detector (SSD) 框架。
OpenCVDNN模块,使用流行的深度学习框架(例如CaffeTensorFlowTorchDarknet)通过预先训练的深度网络实现前向计算(即推理阶段)。这意味着我们可以使用预训练的网络执行完整的前向计算并利用输出在我们的应用程序中进行预测,而不需要花费数小时来训练网络。
接下来,我们预训练的深度学习人脸检测器模型执行人脸检测,使用以下两种模型:

  • 人脸检测器 (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()

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

detected_faces=0w,h=image.shape[1],image.shape[0]# 迭代所有检测结果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()

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


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

3.2 使用 dlib 进行人脸检测

3.2.1 基于 HOG 特征和滑动窗口的人脸检测器

dlib中提供了基于方向梯度直方图 (Histogram of Oriented Gradients,HOG) 特征和滑动窗口检测方法中的线性分类器,使用基于结构SVM的训练算法用于人脸检测,分类器能够在每个训练图像的所有子窗口中进行训练,此人脸检测器使用来自户外标记人脸 (Labeled Faces in the Wild, LFW) 数据集的 3,000 张图像进行了训练。
如需使用dlib中的基于HOG特征和滑动窗口的人脸检测器检测人脸,第一步是从dlib加载人脸检测器:

# 加载人脸检测器# 第二种方法的第一行代码detector=dlib.get_frontal_face_detector()# 加载图像并转换为灰度图像img=cv2.imread('example.png')gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

下一步是执行检测:

# 执行检测# 第二种方法的第二行代码,至此第二种方法也讲解完毕了rects_1=detector(gray,0)rects_2=detector(gray,1)

detector()的第二个参数表示在执行检测过程之前对图像进行上采样的次数,因为图像越大检测器检测到更多的人脸的可能性就越高,但执行时间相应也会增加。
最后可视化检测结果:

defshow_detection(image,faces):forfaceinfaces:cv2.rectangle(image,(face.left(),face.top()),(face.right(),face.bottom()),(255,255,0),5)returnimage# 绘制检测框img_faces_2=show_detection(img.copy(),rects_2)img_faces_2=show_detection(img.copy(),rects_2)# 绘制图像show_img_with_matplotlib(img_faces_1,"detector(gray, 0): "+str(len(rects_1)),1)show_img_with_matplotlib(img_faces_2,"detector(gray, 1): "+str(len(rects_2)),2)plt.show()

如上图所示,如果使用原始灰度图像 (rects_1 = detection(gray, 0)) 检测人脸,则只能找到三张人脸。但是,如果我们使用上采样 1 次的灰度图像 (rects_2 = detection(gray, 1)) 检测人脸,则可以正确的检测到四个人脸。
值得注意的是,该检测器同样也可以用于发现人脸以外的目标。可以通过查看dlib库中的 train_object_detector.py 源码,了解如何仅使用少量训练图像训练自定义对象检测器。例如,可以仅使用十张交通标志图像来训练出色的交通标志检测器。

3.2.2 基于 CNN 的人脸检测器

dlib库同样也提供了CNN人脸检测器,可以使用dlib.cnn_face_detection_model_v1()创建CNN人脸检测器。dlib.cnn_face_detection_model_v1()函数从传入的文件加载人脸检测模型,因此首先下载预训练模型。创建CNN人脸检测器时,将下载完成的预训练模型传递给此方法:

cnn_face_detector=dlib.cnn_face_detection_model_v1("mmod_human_face_detector.dat")

之后,我们使用此检测器来检测人脸:

rects=cnn_face_detector(img,0)

检测器返回mmod_rectangles对象,它是一个mmod_rectangle对象的列表,并且mmod_rectangle对象有两个成员变量——dlib.rectangle对象和预测的置信度分数,为了显示检测结果,编写show_detection()函数:

defshow_detection(image,faces):"""使用矩形检测框显式标示每个检测到的人脸"""forfaceinfaces:cv2.rectangle(image,(face.rect.left(),face.rect.top()),(face.rect.right(),face.rect.bottom()),(255,255,0),5)returnimage# 绘制检测框img_faces=show_detection(img.copy(),rects)# 可视化show_img_with_matplotlib(img_faces,"cnn_face_detector(img, 0): "+str(len(rects)),1)plt.show()

dlib-CNN人脸检测器比dlib-HOG人脸检测器准确得多,但需要更多的算力来运行。例如,对于600 x 400的图像,HOG人脸检测器需要大约 0.25 秒,而CNN人脸检测器却需要大约 5 秒。因此,为了加快CNN人脸检测器的执行速度,则可以通过在含有GPU的计算机上启用CUDA以达到合理的速度,但是需要从源码编译安装dlib

3.3 使用 face_recognition 进行人脸检测

使用face_recognition检测人脸,仅需要调用face_locations()函数:

# 第三种方法需要且仅需要一行代码rects_1=face_recognition.face_locations(rgb,0,"hog")rects_2=face_recognition.face_locations(rgb,1,"hog")

face_locations()的第一个参数是输入图像 (RGB);第二个参数设置在执行检测之前对输入图像上采样的次数;第三个参数是要使用的人脸检测模型。
上述示例使用hog检测模型,此外face_locations()也可以配置为使用cnn人脸检测器检测人脸:

# 使用 cnn 人脸检测器检测人脸rects_1=face_recognition.face_locations(rgb,0,"cnn")rects_2=face_recognition.face_locations(rgb,1,"cnn")

最后可视化检测结果:

defshow_detection(image,faces):forfaceinfaces:top,right,bottom,left=face cv2.rectangle(image,(left,top),(right,bottom),(255,255,0),10)returnimage# 显示检测结果img_faces_1=show_detection(img.copy(),rects_1)img_faces_2=show_detection(img.copy(),rects_2)show_img_with_matplotlib(img_faces_1,"face_locations(rgb, 0, hog): "+str(len(rects_1)),1)show_img_with_matplotlib(img_faces_2,"face_locations(rgb, 1, hog): "+str(len(rects_2)),2)plt.show()

3.4 使用 cvlib 进行人脸检测

最后我们介绍cvlib包中的人脸检测算法。cvlib中提供了detect_face()函数用于检测人脸,在底层,此函数使用OpenCV DNN人脸检测器和预训练的Caffe模型,函数返回所有检测到的人脸的边界框和相应的置信度:

importcvlibascv# 第四种方法同样需要且仅需要一行代码faces,confidences=cv.detect_face(image)# 绘制边界框defshow_detection(image,faces):for(startX,startY,endX,endY)infaces:cv2.rectangle(image,(startX,startY),(endX,endY),(255,0,0),3)returnimage# 可视化img_result=show_detection(img.copy(),faces)show_img_with_matplotlib(img_result,"cvlib face detector: "+str(len(faces)),1)plt.show()

小结

本文中我们介绍了人脸处理包含的主要主题,同时介绍了相关库的安装,并介绍了利用OpenCVdlibface_recognitioncvlib进行人脸检测的相关方法,在后续的系列中,我们将了解包括人脸识别在内的所有人脸处理主题。

系列链接

OpenCV-Python实战(1)——OpenCV简介与图像处理基础
OpenCV-Python实战(2)——图像与视频文件的处理
OpenCV-Python实战(3)——OpenCV中绘制图形与文本
OpenCV-Python实战(4)——OpenCV常见图像处理技术
OpenCV-Python实战(5)——OpenCV图像运算
OpenCV-Python实战(6)——OpenCV中的色彩空间和色彩映射
OpenCV-Python实战(7)——直方图详解
OpenCV-Python实战(8)——直方图均衡化
OpenCV-Python实战(9)——OpenCV用于图像分割的阈值技术
OpenCV-Python实战(10)——OpenCV轮廓检测
OpenCV-Python实战(11)——OpenCV轮廓检测相关应用
OpenCV-Python实战(12)——一文详解AR增强现实
OpenCV-Python实战(13)——OpenCV与机器学习的碰撞
OpenCV-Python实战(15)——面部特征点检测详解
OpenCV-Python实战(16)——人脸追踪详解
OpenCV-Python实战(17)——人脸识别详解
OpenCV-Python实战(18)——深度学习简介与入门示例
OpenCV-Python实战(19)——OpenCV与深度学习的碰撞
OpenCV-Python实战(20)——OpenCV计算机视觉项目在Web端的部署
OpenCV-Python实战(21)——OpenCV人脸检测项目在Web端的部署
OpenCV-Python实战(22)——使用Keras和Flask在Web端部署图像识别应用
OpenCV-Python实战(23)——将OpenCV计算机视觉项目部署到云端
OpenCV-Python实战(24)——打造实时图像滤镜系统
OpenCV-Python实战(25)——基于深度传感器与凸性分析打造实时手势识别系统
OpenCV-Python实战(26)——复杂场景下的实时物体检测与跟踪
OpenCV-Python实战(27)——基于对极几何的3D场景重建
OpenCV-Python实战(28)——OpenCV计算摄影从HDR图像融合到全景拼接
OpenCV-Python实战(29)——基于视觉显著性的自动多目标跟踪系统
OpenCV-Python实战(30)——基于支持向量机的交通标志识别模型
OpenCV-Python实战(31)——实时面部情绪检测与识别系统
OpenCV-Python实战(32)——基于深度学习的物体分类与定位
OpenCV-Python实战(33)——构建实时目标检测与跟踪系统

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询