使用opencv实现人脸检测:Haar级联分类器

本文详细介绍了人脸检测的基础概念、常用算法(如CNN、Eigenface、Fisherfaces等)及其原理,重点讲解了OpenCV中的Haar级联分类器在人脸检测中的应用,并提供了使用OpenCV进行静态图像和视频人脸检测的示例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 人脸检测介绍

1.1 什么是人脸检测

人脸检测的目标是确定图像或视频中是否存在人脸。如果存在多个面,则每个面都被一个边界框包围,因此我们知道这些面的位置。

人脸检测算法的主要目标是准确有效地确定图像或视频中人脸的存在和位置。这些算法分析数据的视觉内容,搜索与面部特征相对应的模式和特征。通过采用机器学习、图像处理和模式识别等各种技术,人脸检测算法旨在将人脸与视觉数据中的其他对象或背景元素区分开来。

人脸很难建模,因为有许多变量可以改变,例如面部表情、方向、照明条件以及太阳镜、围巾、口罩等部分遮挡。检测结果给出了面部位置参数,并且可以要求有多种形式,例如覆盖面部中央部分、眼睛中心或包括眼睛、鼻子和嘴角、眉毛、鼻孔等的标志的矩形。

1.2 常用的人脸检测算法

在人们日常生活中,最常见的生物识别方式一定是人脸识别,身份验证、门禁、监控等都需要用上人脸识别。对于数据结构工程师和算法工程师来说,人脸识别算法是需要接触的常见算法之一。那本文列举了七种最常见的人脸识别算法。

  • 卷积神经网络(CNN)

卷积神经网络(CNN)是一类包含卷积计算且具有深度结构的前馈神经网络,也是人工神经网络和人工智能的常见算法之一,隶属于机器学习中的深度学习。它的原理是:模型学习直接对图像、视频、文本或声音执行分类结果。它常用于计算机视觉、自然语言处理和最大的图像分类数据集。

  • 特征脸(Eigenface)

特征脸(Eigenface)是指用于机器视觉领域中的人脸识别问题的一组特征向量,用于确定图像数据集中的人脸方差,被认为是第一种有效的人脸识别方法。原理是通过机器学习对人脸进行编码解码。一组特征脸是通过对大量人脸图像的统计分析确定的“标准化人脸成分”的集合,注意这种算法不使用数字图片,而是通过统计数据库,面部特征被分配数字值,人脸是这些值以不同百分比的组合。

  • Fisherfaces

Fisherfaces是最流行的人脸识别算法之一,是特征脸(Eigenface)算法的延伸品,在训练过程中的类别区分方面比特征脸更加优秀。Fisherfaces的优点在于它能够对光照和面部表情变化进行内插和外推。若在与处理阶段与PCA方法结合,算法准确度高达93%。

  • 内核方法:PCA和SVM

主成分分析(PCA)是一种有用的通用统计方法,在人脸识别过程中,PCA能减少源数据同时保留最相关的信息,原理是:生成一组加权特征向量,这些特征向量依次构建特征脸(大量不同的人脸图像),而这些人脸图像的线性组合代表训练集中的每个图像,PCA作用是从训练图像集的协方差矩阵中接收这些特征向量。

支持向量机(SVM)属于机器学习算法,它使用两组分类原则来区分人脸和非人脸,对于每个类别,SVM模型将接收一个标记的训练数据集来对新的测试数据进行分类。

  • Haar Cascade

Haar Cascade是一种用于在图像上定位对象的对象检测方法,他将从大量正样本和负样本中学习,前者包括感兴趣的对象,后者包括除你要查找对象之外的任何内容。训练后,分类器可在新图像上找到感兴趣的对象。Haar Cascade常与局部二值模式算法结合用于刑事鉴定的人脸识别。

  • 三维识别

3D人脸识别的基本原理是人类头骨的独特结构,人的头骨结构具有独特性,可用几十个参数来描述,它的原理是将3D面部扫描与数据库模式进行比较,它最大的优势是不会因为化妆、面部毛发等外界因素影响到检测识别。

  • 皮肤纹理分析

皮肤纹理识别通常使用高分辨率图像。皮肤纹理分析的特殊情况使用不同的独特参数,如痣、肤色、肤色等,常用于人脸检测、不良图像过滤、手势分析等。

1.3 Haar级联分类器

人脸检测是计算机视觉中的一个重要任务,在现实生活中有着广泛的应用价值。Haar级联分类器是OpenCV中实现人脸检测其中一种算法,它通过分析相邻图像区域之间的对比度,确定给定图像或子图像是否与已知类型匹配。我们来考虑如何在层次结构中组合多个Haar级联分类器,以便用一个分类器识别父区域(就目标而言是一张人脸),用其他分类器识别子区域(比如眼睛)。在OpenCV源代码的副本中会有一个文件data/haarcascades。该文件夹包含了所有OpenCV的人脸检测的XML文件,这些文件可用于检测静止图像、视频和摄像头所得到图像中的人脸。

从文件名可知这些级联是用于人脸、眼睛、鼻子和嘴的跟踪。这些文件需要正面、直立的人脸图像。创建人脸检测器时会使用这些文件,创建自己的级联,并训练这些级联来检测各种对象。

1df37fc7bcc049c78a2f7107bfdd7f31.png

代码地址: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个人脸!

 06f0fa9b3ece4fa98819d1ec1b32dd59.png

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()


运行结果显示如下:

2733c69f6c4744f586b3a6e3510915ef.png

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
检测到人脸
检测到人脸
检测到人脸
检测到人脸
检测到人脸
检测到人脸

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

智慧医疗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值