使用 Haar 级联分类器的 OpenCV 人脸检测

Salman Mehmood 2024年2月15日
使用 Haar 级联分类器的 OpenCV 人脸检测

在这个演示中,我们将借助基于 haar 特征的级联分类器学习人脸检测的基础知识,并学习如何在 OpenCV 中从图像和视频中检测人脸。

在 OpenCV 中使用 Haar 级联分类器创建人脸检测项目

使用基于 Haar 特征的级联分类器进行对象检测是 Paul Viola 和 Michael Jones 在他们的研究中提出的一种有效的对象检测方法。Haar 基于特征的级联分类器是一种基于机器学习的方法,其中针对许多正负图像训练级联函数。

那么这些正面和负面的形象是什么?分类器使用特定对象的数百个样本视图进行训练,这些对象可能是人脸、汽车或任何其他称为正例的对象。

例如,如果要检测人脸,则必须使用包含人脸的图像数量来训练分类器。然后,它被称为正面图像。

在另一种情况下,如果要检测人脸并且图像中不包含人脸,则称为负像。

训练分类器后,可以将其应用于输入图像中的感兴趣区域。如果区域可能显示对象,则分类器输出为 1;否则为 0。

让我们看看如何在 OpenCV 中使用 Haar Cascade 检测。

OpenCV 带有一个训练器和一个检测器。如果你想针对手表、汽车或任何物体等任何对象训练分类器,则可以使用此分类器。

我们可以在 OpenCV GitHub 页面上找到一些经过训练的分类器 XML 文件。这个存储库中有大量训练有素的分类器。

OpenCV GitHub 训练的分类器 XML 文件

你只需要打开这个突出显示的文件,然后通过单击原始图标按钮下载它。当它打开时,你可以右键单击并将其保存在你的计算机上。

让我们打开代码编辑器并定义我们的分类器。

有一个名为 CascadeClassifier() 的方法,我们可以在其中提供分类器路径。一旦我们定义了分类器,然后我们读取图像。

F_C = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")

由于此分类器将处理灰度图像,因此我们需要将图像转换为灰度图像。实现图像转换将非常容易。

IMG = cv2.imread("inp.png")
G_scale = cv2.cvtColor(IMG, cv2.COLOR_BGR2GRAY)

下一步是检测这张图片中的人脸;为此,我们将声明一个名为 Faces 的变量。我们将调用 detectMultiScale() 方法,该方法接受三个参数。

第一个是灰度图像,我们要使用的第二个参数是比例因子,用于指定在每个图像比例下图像尺寸缩小多少。接下来是最小邻居参数,它指定每个候选矩形应该有多少邻居来保留它。

Faces = F_C.detectMultiScale(G_scale, 1.1, 4)

最后一步是遍历我们检测到的所有面部,然后绘制一个矩形。这个 Faces 变量将是矩形的向量,其中每个矩形都包含一个检测到的对象,在我们的例子中,它将是检测到的人脸。

我们将从 Faces 对象中获取参数 (x,y,w,h)。这些是对象矩形的值。

在获取坐标时,我们将使用 rectangle() 方法绘制矩形。

它需要一些参数。第一个是图像,第二个是我们使用 Faces 向量得到的点 (x,y),下一个参数是矩形的第二个点。

接下来的两个参数是颜色和厚度。

import cv2

F_C = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")

IMG = cv2.imread("inp.png")
G_scale = cv2.cvtColor(IMG, cv2.COLOR_BGR2GRAY)
Faces = F_C.detectMultiScale(G_scale, 1.1, 4)

for (x, y, w, h) in Faces:
    cv2.rectangle(IMG, (x, y), (x + w, y + h), (255, 0, 0), 3)

cv2.imshow("IMG", IMG)

cv2.waitKey()

现在我们可以看到在图像中检测到人脸。

OpenCV Haar 级联图像人脸检测输出

让我们尝试检测视频中的人脸,所以这不会是一种不同的方法。我们只需要将这种方法应用于每一帧,因此我们将使用 VideoCapture() 方法来捕获视频,而不是读取图像。

为了捕捉帧,我们需要定义一个 Video 变量并使其等于 VideoCapture() 并提供一个 mp4 文件。如果你有相机,你可以提供它 0。

现在我们将所有上述代码包含在一个 while 循环中,并且在 while 循环中,我们定义 isOpened() 方法。如果此方法返回真值,则程序将继续读取帧;我们将调用 Video.read(),这意味着我们正在读取每一帧。

当有人按下 q 键时,我们将定义一个条件,然后程序将跳出 while 循环。最后,在我们的 while 循环之外,我们将发布我们的视频。

import cv2

F_C = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")

Video = cv2.VideoCapture("inp.mp4")

while Video.isOpened():
    _, IMG = Video.read()

    G_scale = cv2.cvtColor(IMG, cv2.COLOR_BGR2GRAY)
    Faces = F_C.detectMultiScale(G_scale, 1.1, 4)

    for (x, y, w, h) in Faces:
        cv2.rectangle(IMG, (x, y), (x + w, y + h), (255, 0, 0), 3)

    cv2.imshow("Window", IMG)
    K = cv2.waitKey(1)
    if K & 0xFF == ord("q"):
        break

Video.release()

在这段视频中,我们可以看到实时视频中检测到的人脸。

OpenCV Haar 级联视频人脸检测输出

作者: Salman Mehmood
Salman Mehmood avatar Salman Mehmood avatar

Hello! I am Salman Bin Mehmood(Baum), a software developer and I help organizations, address complex problems. My expertise lies within back-end, data science and machine learning. I am a lifelong learner, currently working on metaverse, and enrolled in a course building an AI application with python. I love solving problems and developing bug-free software for people. I write content related to python and hot Technologies.

LinkedIn

相关文章 - Python OpenCV