虽然互联网上有很多关于 OpenCV 的 Haar Cascade 对象检测模块这方面的技术资料,但这篇文章的重点是通俗易懂地解释这些概念,希望这能帮助初学者以简单的方式理解 Python 的 OpenCV 库。
在本演示中,我们将拍摄一张图片并在其中搜索人脸,我们将使用预先训练好的分类器来执行此搜索,现在让我们开始使用预先训练的模型吧。
对于初学者来说,OpenCV 是一个 Python 库,主要用于各种计算机视觉问题。
在这里,我们使用“ haarcascade_frontalface_default.xml ”作为 opencv github 存储库的模型。小伙伴们可以下载此 xml 文件并将其放置在与 python 文件相同的路径中,并且这里还有许多其他模型(例如:眼睛检测、全身检测、猫脸检测等)。
在开始编写代码之前,让我们先看一下程序的高级流程。
下面描述的整个过程的图[输入、人脸检测过程&输出]
输入:
该算法需要两个输入:
- 输入图像矩阵(我们将读取图像并将其转换为数字矩阵/numpy 数组)
- 面部特征(在haarcascade_frontalface_default.xml文件中可用)
人脸检测流程:
OpenCV 的 Haar Cascade 分类器采用滑动窗口方法。在这种方法中,一个窗口(默认大小为 20 x 20 像素)在图像上滑动(逐行)以查找面部特征。每次迭代后,图像都会按特定因子(由参数“ scaleFactor ”确定)按比例缩小(调整大小)。存储每次迭代的输出,并在较小的、调整大小的图像上重复滑动操作。在初始迭代过程中可能会出现误报,本文稍后将对此进行更详细的讨论。这种缩小和窗口化过程一直持续到图像对于滑动窗口来说太小为止,scaleFactor 的值越小,精度越高。
输出:
我们的输出图像将在每个检测到的人脸周围包含一个矩形。
代码和解释:
让我们从 python 代码开始。本实验需要以下 Python 包:
代码语言:javascript复制pip install numpy
pip install opencv-python
让我们将 python 文件命名为“face_detector.py”,并将其放置在与从上面共享的 github 链接下载的 xml 文件相同的路径中。
代码语言:javascript复制# File Name: face_detector.py
# Import the OpenCV library
import cv2
现在让我们看看承诺的 10 行!
我们准备了 2 个输入 [input image&face features xml],如上一节的流程图所示。
我们使用下面这张美丽的照片作为我的输入图像 。
我们首先加载我们的 xml 分类器和输入图像文件。由于输入文件非常大,我们需要调整大小,尺寸与原始分辨率相似,以免它们出现拉伸。然后,我们将图像转换为灰度图像,因为灰度图像被认为可以提高算法的效率。
代码语言:javascript复制face_cascade = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
image = cv2.imread("kids.jpg")
image = cv2.resize(image, (800,533))
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
读取的图像存储为多维 numpy 数组,如下所示。
代码语言:javascript复制print(type(gray_image))
<class 'numpy.ndarray'>
在下一步中,我们将灰度图像作为输入传递给 detectMultiScale 方法,该方法将为我们执行检测。它采用以下参数:
scaleFactor :此参数指定图像缩小的因子,例如:如果此值为 1.05,则图像缩小 5%;如果此值为 1.10,则图像按比例缩小 10%。1.10 的 scaleFactor 比 1.05 的 scaleFactor 需要更少的计算。
minNeighbors :它是一个阈值,指定每个矩形应该有多少个相邻矩形才能将其标记为真阳性。换句话说,让我们假设每次迭代都标记某些矩形(即将图像的一部分分类为人脸)。现在,如果后续的迭代也将相同的区域标记为正,则该矩形区域成为真正的可能性就会增加。如果某个区域在一次迭代中被识别为人脸,但在任何其他迭代中都没有,则将它们标记为误报。换句话说,minNeighbors 是一个区域必须被确定为人脸的最小次数。
让我们进行一个实验来更好地理解它。我们将使用不同的 minNeighbors 参数值运行我们的代码。
对于minNeighbors = 0,所有的矩形都被检测为人脸。对于某些矩形,有很多重叠的矩形,这表明在多次迭代中这些矩形已被检测为正。我们设置阈值以提高算法的准确性。
minNeighbors = 0
当 minNeighbors = 2 时,大部分重叠矩形不再存在。但是,我们仍然有一些误报。
minNeighbors = 2
如果我们将此阈值增加到 4 或 5,我们可以看到不再有误报,让我们将此值设置为 5 并继续进行。
代码语言:javascript复制faces=face_cascade.detectMultiScale(gray_image,scaleFactor=1.10,minNeighbors=5)
detectMultiScale方法返回一个numpy数组,其中包含面所在矩形的尺寸和位置。
x , y — 矩形左上角的位置 ;w , h — 矩形的宽度和高度
我们现在用绿色 ( 0 , 255 , 0 )( BGR 颜色代码)绘制这些尺寸的矩形,边框厚度为 1。
窗口等待 2 秒(2000 毫秒)并自动关闭。
代码语言:javascript复制for x,y,w,h in faces:
image=cv2.rectangle(image, (x,y), (x w, y h), (0, 255, 0),1)
cv2.imshow("Face Detector", image)
k=cv2.waitKey(2000)
cv2.destroyAllWindows()
或者,我们也可以通过添加下面的行来保存图像。
代码语言:javascript复制cv2.imwrite("kids_face_detected.jpeg", image)
我们的输出图像现在包含每个检测到的人脸周围的绿色矩形。
minNeighbors = 5
希望这篇文章能让我们对如何在 Python 中使用 OpenCV 进行人脸检测有一个基本的了解,我们也可以扩展此代码以跟踪视频中的人脸。
Github代码连接:
https://github.com/arindomjit/Face_Detector