OpenCV实例(一)人脸检测
- 1.人脸检测和识别概述
- 2.使用OpenCV进行人脸检测
- 2.1静态图像中的人脸检测
- 2.2视频中的人脸检测
作者:Xiou
1.人脸检测和识别概述
计算机视觉使很多任务成为现实,其中两项任务就是人脸检测(在图像中定位人脸)和人脸识别(将人脸识别为特定的人)。OpenCV实现了一些人脸检测和识别的算法。从安全到娱乐,这些技术在现实环境中都有应用。
介绍OpenCV的一些人脸检测和识别功能,并定义特定类型的可跟踪物体的数据文件。具体来说,将研究Haar级联分类器,通过分析相邻图像区域之间的对比度,确定给定图像或子图像是否与已知类型匹配。我们来考虑如何在层次结构中组合多个Haar级联分类器,以便用一个分类器识别父区域(就我们的目标而言,是一张人脸),用其他分类器识别子区域(比如眼睛)。
在OpenCV 3源代码的副本中会有一个文件夹data/haarcascades。该文件夹包含了所有OpenCV的人脸检测的XML文件,这些文件可用于检测静止图像、视频和摄像头所得到图像中的人脸。
找到haarcascades文件夹后,为项目创建一个文件夹,然后在该文件夹中创建名为cascades的子文件夹,并将haarcascades文件夹中的所有文件复制到cascades文件夹中:
从文件名可知这些级联是用于人脸、眼睛、鼻子和嘴的跟踪。这些文件需要正面、直立的人脸图像。在稍后创建人脸检测器时会使用这些文件。有了很大的耐心以及强大的计算机,就可以创建自己的级联,并训练这些级联来检测各种对象。
模型下载链接:
https://download.csdn.net/download/weixin_46274168/20822795
2.使用OpenCV进行人脸检测
在静态图像或视频中检测人脸的操作非常相似。视频人脸检测只是从摄像头读出每帧图像,然后采用静态图像中的人脸检测方法进行检测。当然,视频人脸检测还涉及其他的概念,例如跟踪,而静态图像中的人脸检测就没有这样的概念,但它们的基本理论是一致的。
2.1静态图像中的人脸检测
人脸检测首先是加载图像并检测人脸,这也是最基本的一步。为了使所得到的结果有意义,可在原始图像的人脸周围绘制矩形框。现在,项目中已经包含了haarcascades文件夹的内容,下面创建一个基本的脚本来实现人脸检测。
在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('girl1.jpg')
# 获取XML文件,加载人脸检测器
faceCascade = cv2.CascadeClassifier('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.circle(image, (int((x + x + w) / 2), int((y + y + h) / 2)), int(w / 2), (0, 255, 0), 2)
# 显示结果
cv2.imshow("dect", image)
# 保存检测结果
cv2.imwrite("re.jpg", image)
cv2.waitKey(0)
cv2.destroyAllWindows()
输出结果:
我们逐步浏览一下前面的代码。首先,使用必要的cv2导入,本书的每个脚本都有这个导入。然后,声明一个face_cascade变量,这是一个CascadeClassifier对象,用于加载人脸检测级联。
然后,用cv2.imread加载图像文件,将其转换成灰度图像,因为Cascade Classifier需要灰度图像。下一步,用face_cascade.detectMultiScale进行实际的人脸检测。
detectMultiScale的参数包括scaleFactor和minNeighbors。scaleFactor参数应该大于1.0,确定人脸检测过程中每次迭代时图像的降尺度比率。minNeighbors参数是为了保留检测结果所需要的最小重叠检测次数。通常,我们期望可以在多个重叠窗口中检测到某人脸,更多的重叠检测使我们更加确信检测到的人脸是一个真正的人脸。
2.2视频中的人脸检测
现在,我们了解了如何在静态图像上进行人脸检测。如前所述,我们可以在视频(摄像头回传信号或者预先录制的视频文件)的每一帧上重复人脸检测的过程。
下一个脚本将打开一个摄像头回传信号,读取一帧,检查该帧中的人脸,并在检测到的人脸内扫描眼睛。最后,在人脸周围绘制蓝色的矩形,在眼睛周围绘制绿色的矩形。
代码实例:
import cv2
face_cascade = cv2.CascadeClassifier(
'./cascades/haarcascade_frontalface_default.xml')
eye_cascade = cv2.CascadeClassifier(
'./cascades/haarcascade_eye.xml')
camera = cv2.VideoCapture(0)
while (cv2.waitKey(1) == -1):
success, frame = camera.read()
if success:
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(
gray, 1.3, 5, minSize=(120, 120))
for (x, y, w, h) in faces:
cv2.rectangle(frame, (x, y), (x+w, y+h), (255, 0, 0), 2)
roi_gray = gray[y:y+h, x:x+w]
eyes = eye_cascade.detectMultiScale(
roi_gray, 1.1, 5, minSize=(40, 40))
for (ex, ey, ew, eh) in eyes:
cv2.rectangle(frame, (x+ex, y+ey),
(x+ex+ew, y+ey+eh), (0, 255, 0), 2)
cv2.imshow('Face Detection', frame)
(1)像往常一样,导入cv2模块。之后,初始化两个CascadeClassifier对象,一个用于人脸,另一个用于眼睛。
(2)就像大多数交互式脚本一样,打开一个摄像头回传信号,开始迭代帧。继续,直到用户按下某个键。当成功捕捉到一帧时,将其转换为灰度作为处理的第一步。
(3)利用人脸检测器的detectMultiScale方法对人脸进行检测。正如之前所述,我们使用了scaleFactor和minNeighbors参数。我们还使用minSize参数指定了人脸的最小尺寸,具体为120×120,因此不会尝试去检测比这个尺寸小的脸。(假设用户坐在摄像头附近,可以有把握地说,图像中用户的脸将大于120×120像素。)以下是对detectMultiScale的调用:
(4)迭代检测到的人脸。在原始彩色图像的每个矩形周围绘制一个蓝色边界。然后,在灰度图像的同一个矩形区域内进行眼睛检测:
(5)循环遍历生成的眼睛矩形,并在其周围绘制绿色轮廓:
(6)最后,在窗口中显示生成的帧。
输出结果:
用此脚本进行实验,研究人脸和眼睛检测器在不同条件下的表现。试着在更亮或更暗的房间进行。如果戴着眼镜,试着摘掉眼镜再进行一次。尝试在不同人脸和不同的表情下进行。调整脚本中的检测参数,看看这些参数对结果的影响。当你感到满意时,我们再来考虑在OpenCV中还可以做些什么。