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

📅 2026/7/21 15:55:37
OpenCV-Python实战(14)——人脸检测详解(仅需6行代码学会4种人脸检测方法)
OpenCV-Python实战14——人脸检测详解仅需6行代码学会4种人脸检测方法0. 前言1. 人脸处理简介2. 安装人脸处理相关库2.1 安装 dlib2.2 安装 face_recognition2.3 安装 cvlib3. 人脸检测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)检查检测到的人脸是否是其所声称的人如上所述人脸处理主要包括人脸检测、面部特征点检测、人脸追踪和人脸识别本文主要关注使用OpenCV、dlib、face_recognition和cvlib库进行人脸检测关于其他人脸处理主题将在后续系列中进行介绍。2. 安装人脸处理相关库2.1 安装 dlibDlib 是一个包含计算机视觉、机器学习和深度学习算法的 C 软件库也可以在Python应用程序中使用安装dlib需要使用以下命令pipinstalldlib2.2 安装 face_recognitionface_recognition 是一个强大、简单、易上手的人脸识别开源项目为了在Python中使用face_recognition库使用以下命令进行安装pipinstallface_recognition2.3 安装 cvlibcvlib一个高级、易用、开源的Python计算机视觉库要安装 cvlib 包首先需要安装以下依赖库numpy、opencv-python、requests、progressbar、pillow、tensorflow以及keras。然后再安装cvlib包pipinstallcvlib3. 人脸检测人脸检测是确定图像中人脸的位置和大小的任务通常是构建人脸处理应用程序(例如表情识别、睡意检测、性别分类、人脸识别或人机交互等)的基础这是由于此类应用程序需要将检测到的人脸位置和大小作为输入。因此自动人脸检测起着至关重要的作用是人工智能学科研究最多的课题之一。人脸检测对人类而言并不困难但对计算机来说通常涉及许多挑战(例如外观变化、比例变换、旋转、面部表情变换、遮挡或光照条件等)。在本节中我们将利用OpenCV、dlib和face_processing等提供的流行人脸检测技术(包括机器学习和深度学习方法)检测图像中的人脸。3.1 使用 OpenCV 进行人脸检测OpenCV提供了两种人脸检测方法包括基于 Haar 级联的人脸检测器基于深度学习的人脸检测器3.1.1 基于 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_alt2cv2.CascadeClassifier(haarcascade_frontalface_alt2.xml)cas_defaultcv2.CascadeClassifier(haarcascade_frontalface_default.xml)接下来就可以使用cv2.CascadeClassifier.detectMultiScale()函数执行检测了# 第一种方法的第二行代码# 这样就完成了第一种方法的介绍了faces_alt2cas_alt2.detectMultiScale(gray)faces_defaultcas_default.detectMultiScale(gray)cv2.CascadeClassifier.detectMultiScale()函数检测对象并将它们作为矩形列表返回。为了进行可视化最后编写show_detection()函数进行可视化defshow_detection(image,faces):在每个检测到的人脸上绘制一个矩形进行标示for(x,y,w,h)infaces:cv2.rectangle(image,(x,y),(xw,yh),(255,0,0),5)returnimage# 调用 show_detection() 函数标示检测到的人脸img_faces_alt2show_detection(img.copy(),faces_alt2)img_faces_defaultshow_detection(img.copy(),faces_default)什么两行代码还觉得麻烦那么是时候用一行调用检测器并检测人脸了这就是OpenCV提供的cv2.face.getFacesHAAR()函数# 一行代码实现基于 Haar 级联的人脸检测器学一送一retval,faces_haar_alt2cv2.face.getFacesHAAR(img,haarcascade_frontalface_alt2.xml)retval,faces_haar_defaultcv2.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_alt2np.squeeze(faces_haar_alt2)faces_haar_defaultnp.squeeze(faces_haar_default)从加载的图像到检测和绘制人脸的完整代码如下# 可视化函数defshow_img_with_matplotlib(color_img,title,pos):img_RGBcolor_img[:,:,::-1]axplt.subplot(2,2,pos)plt.imshow(img_RGB)plt.title(title,fontsize8)plt.axis(off)# 加载图像imgcv2.imread(test_face_detection.jpg)# 将 BGR 图像转换为灰度图像graycv2.cvtColor(img,cv2.COLOR_BGR2GRAY)# 加载分类器cas_alt2cv2.CascadeClassifier(haarcascade_frontalface_alt2.xml)cas_defaultcv2.CascadeClassifier(haarcascade_frontalface_default.xml)# 检测人脸faces_alt2cas_alt2.detectMultiScale(gray)faces_defaultcas_default.detectMultiScale(gray)retval,faces_haar_alt2cv2.face.getFacesHAAR(img,haarcascade_frontalface_alt2.xml)faces_haar_alt2np.squeeze(faces_haar_alt2)retval,faces_haar_defaultcv2.face.getFacesHAAR(img,haarcascade_frontalface_default.xml)faces_haar_defaultnp.squeeze(faces_haar_default)# 绘制人脸检测框img_faces_alt2show_detection(img.copy(),faces_alt2)img_faces_defaultshow_detection(img.copy(),faces_default)img_faces_haar_alt2show_detection(img.copy(),faces_haar_alt2)img_faces_haar_defaultshow_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()函数有minSize和maxSize参数用以设置最小尺寸(小于minSize的对象将不被检测)和最大尺寸(大于maxSize的对象将不被检测到)而cv2.face.getFacesHAAR()函数并不提供此参数。3.1.2 基于深度学习的人脸检测器除了基于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 实现的版本netcv2.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()函数进行此预处理blobcv2.dnn.blobFromImage(image,1.0,(300,300),[104.,117.,123.],False,False)下一步是将blob设置为输入以获得结果对整个网络执行前向计算以计算输出# 将 blob 设置为输入并获取检测结果net.setInput(blob)detectionsnet.forward()最后一步是迭代检测并绘制结果仅在相应置信度大于最小阈值时才将其可视化detected_faces0w,himage.shape[1],image.shape[0]# 迭代所有检测结果foriinrange(0,detections.shape[2]):# 获取当前检测结果的置信度confidencedetections[0,0,i,2]# 如果置信大于最小置信度则将其可视化ifconfidence0.7:detected_faces1# 获取当前检测结果的坐标boxdetections[0,0,i,3:7]*np.array([w,h,w,h])(startX,startY,endX,endY)box.astype(int)# 绘制检测结果和置信度text{:.3f}%.format(confidence*100)ystartY-10ifstartY-1010elsestartY10cv2.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加载人脸检测器# 加载人脸检测器# 第二种方法的第一行代码detectordlib.get_frontal_face_detector()# 加载图像并转换为灰度图像imgcv2.imread(example.png)graycv2.cvtColor(img,cv2.COLOR_BGR2GRAY)下一步是执行检测# 执行检测# 第二种方法的第二行代码至此第二种方法也讲解完毕了rects_1detector(gray,0)rects_2detector(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_2show_detection(img.copy(),rects_2)img_faces_2show_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_detectordlib.cnn_face_detection_model_v1(mmod_human_face_detector.dat)之后我们使用此检测器来检测人脸rectscnn_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_facesshow_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_1face_recognition.face_locations(rgb,0,hog)rects_2face_recognition.face_locations(rgb,1,hog)face_locations()的第一个参数是输入图像 (RGB)第二个参数设置在执行检测之前对输入图像上采样的次数第三个参数是要使用的人脸检测模型。上述示例使用hog检测模型此外face_locations()也可以配置为使用cnn人脸检测器检测人脸# 使用 cnn 人脸检测器检测人脸rects_1face_recognition.face_locations(rgb,0,cnn)rects_2face_recognition.face_locations(rgb,1,cnn)最后可视化检测结果defshow_detection(image,faces):forfaceinfaces:top,right,bottom,leftface cv2.rectangle(image,(left,top),(right,bottom),(255,255,0),10)returnimage# 显示检测结果img_faces_1show_detection(img.copy(),rects_1)img_faces_2show_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,confidencescv.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_resultshow_detection(img.copy(),faces)show_img_with_matplotlib(img_result,cvlib face detector: str(len(faces)),1)plt.show()小结本文中我们介绍了人脸处理包含的主要主题同时介绍了相关库的安装并介绍了利用OpenCV、dlib、face_recognition和cvlib进行人脸检测的相关方法在后续的系列中我们将了解包括人脸识别在内的所有人脸处理主题。系列链接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——构建实时目标检测与跟踪系统