1 人脸检测介绍
1.1 什么是人脸检测
人脸检测的目标是确定图像或视频中是否存在人脸。如果存在多个面,则每个面都被一个边界框包围,因此我们知道这些面的位置
人脸检测算法的主要目标是准确有效地确定图像或视频中人脸的存在和位置。这些算法分析数据的视觉内容,搜索与面部特征相对应的模式和特征。通过采用机器学习、图像处理和模式识别等各种技术,人脸检测算法旨在将人脸与视觉数据中的其他对象或背景元素区分开来。
人脸很难建模,因为有许多变量可以改变,例如面部表情、方向、照明条件以及太阳镜、围巾、口罩等部分遮挡。检测结果给出了面部位置参数,并且可以要求有多种形式,例如覆盖面部中央部分、眼睛中心或包括眼睛、鼻子和嘴角、眉毛、鼻孔等的标志的矩形。
1.2 Haar级联分类器
人脸检测是计算机视觉中的一个重要任务,在现实生活中有着广泛的应用价值。Haar级联分类器是OpenCV中实现人脸检测其中一种算法,它通过分析相邻图像区域之间的对比度,确定给定图像或子图像是否与已知类型匹配。我们来考虑如何在层次结构中组合多个Haar级联分类器,以便用一个分类器识别父区域(就目标而言是一张人脸),用其他分类器识别子区域(比如眼睛)。在OpenCV源代码的副本中会有一个文件夹data/haarcascades。该文件夹包含了所有OpenCV的人脸检测的XML文件,这些文件可用于检测静止图像、视频和摄像头所得到图像中的人脸。
从文件名可知这些级联是用于人脸、眼睛、鼻子和嘴的跟踪。这些文件需要正面、直立的人脸图像。创建人脸检测器时会使用这些文件,创建自己的级联,并训练这些级联来检测各种对象。
代码地址:https://github.com/opencv/opencv/tree/4.x/data/haarcascades
2 使用opencv进行人脸检测
在静态图像或视频中检测人脸的操作非常相似。视频人脸检测只是从摄像头读出每帧图像,然后采用静态图像中的人脸检测方法进行检测。当然,视频人脸检测还涉及其他的概念,例如跟踪,而静态图像中的人脸检测就没有这样的概念,但它们的基本理论是一致的。
2.1 静态图像人脸检测
检测步骤为读取静态图像,调用模型进行检测。
在OpenCV中,人脸检测使用的是cv2.CascadeClassifier.detectMultiScale()函数,它可以检测出图片中所有的人脸。
cv2.detectMultiScale(self, image, scaleFactor=None, minNeighbors=None, flags=None, minSize=None, maxSize=None)
参数:
image: 输入图像, 灰度图;
scaleFactor: 图像尺寸缩小比例, 决定两个不同大小的窗口扫描之间有多大的跳跃;
minNeighbors: 被检测到几次才算目标;
minSize: 目标最小尺寸;
maxSize: 目标最大尺寸;
人脸检测代码:
import cv2
image = cv2.imread('../data/girl01.jpg')
# 获取XML文件,加载人脸检测器
faceCascade = cv2.CascadeClassifier('../data/haarcascade_frontalface_default.xml')
# 色彩转换,转换为灰度图像
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 调用函数detectMultiScale
faces = faceCascade.detectMultiScale(gray, scaleFactor=1.15, minNeighbors=5, minSize=(5, 5))
print(faces)
print("发现{0}个人脸!".format(len(faces)))
# 逐个标注人脸
for (x, y, w, h) in faces:
cv2.rectangle(image, (x, y), (x+w, y+w), (0, 255, 0), 2)
cv2.imshow("face", image)
cv2.imwrite("../data/detect_result.jpg", image)
cv2.waitKey(0)
cv2.destroyAllWindows()
检测结果如下:
[[242 115 159 159]]
发现1个人脸!
人眼检测代码:
2.2 视频人脸检测
检测步骤为读取视频的每一帧图像,对每一帧图像逐一进行人脸检测
import cv2
# 1.读取视频
cv2.namedWindow("CaptureFace")
cap = cv2.VideoCapture('../data/girl.mp4')
# 2.人脸识别器分类器
classfier = cv2.CascadeClassifier('../data/haarcascade_frontalface_alt2.xml')
color = (0, 255, 0)
while cap.isOpened():
flag, frame = cap.read()
frame = cv2.flip(frame, 1) # 镜像操作
if not flag:
break
# 3.灰度转换
grey = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 4.人脸检测,1.2和2分别为图片缩放比例和需要检测的有效点数
facerects = classfier.detectMultiScale(grey, scaleFactor=1.2, minNeighbors=3, minSize=(32, 32))
if len(facerects) > 0: # 大于0则检测到人脸
for faceRect in facerects: # 单独框出每一张人脸
x, y, w, h = faceRect
# 5.画图
cv2.rectangle(frame, (x - 10, y - 10), (x + w + 10, y + h + 10), color, 3)
cv2.imshow("CaptureFace", frame)
if cv2.waitKey(10) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
运行结果显示如下:
2.3 摄像头人脸检测
检测步骤为打开摄像头,捕获摄像头的每一帧数据,针对每一帧数据进行检测
import cv2
# 1.调用摄像头
cv2.namedWindow("CaptureFace")
cap = cv2.VideoCapture(0, cv2.CAP_DSHOW)
# 2.人脸识别器分类器
classfier = cv2.CascadeClassifier('../data/haarcascade_frontalface_alt2.xml')
color = (0, 255, 0)
while cap.isOpened():
flag, frame = cap.read()
frame = cv2.flip(frame, 1) # 镜像操作
if not flag:
break
# 3.灰度转换
grey = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 4.人脸检测,1.2和2分别为图片缩放比例和需要检测的有效点数
facerects = classfier.detectMultiScale(grey, scaleFactor=1.2, minNeighbors=3, minSize=(32, 32))
if len(facerects) > 0: # 大于0则检测到人脸
print('检测到人脸')
for faceRect in facerects: # 单独框出每一张人脸
x, y, w, h = faceRect
# 5.画图
cv2.rectangle(frame, (x - 10, y - 10), (x + w + 10, y + h + 10), color, 3)
cv2.imshow("CaptureFace", frame)
if cv2.waitKey(10) & 0xFF == ord('q'):
break
检测到人脸
检测到人脸
检测到人脸
检测到人脸
检测到人脸
检测到人脸