目录
简介
要实现人脸识别首先要判断当前图像中是否出现了人脸,这就是人脸检测。只有检测到图像中出现了人脸,才能据此判断这个人到底是谁。
Opencv如何实现人脸识别?
调用 OpenCV 中训练好的分类器实现人脸检测。OpenCV 提供了训练好的haar级联分类器,OpenCV 还提供了使用 HOG 特征(主要用于行人检测)和 LBP 算法的级联分类器。
一、人脸检测
1.haar特征
特征值 = ∑特征区域中白色区域的像素值-黑色区域像素值 Haar特征反映的是图像的灰度变化

关于 Harr 特征中的矩形框,有如下 3 个变量:
• 矩形框位置: 矩形框要逐像素点地划过(遍历) 整个图像获取每个位置的特征值。
• 矩形框大小: 矩形的大小可以根据需要进行任意调整。
• 矩形框类型: 包含垂直、水平、对角等不同类型。
2.级联分类器


Haar级联分类器
Haar级联分类器是一种基于特征提取和机器学习的对象检测方法。它使用Haar特征进行图像分析,通过训练样本数据集,生成一个多层级联的分类器来检测目标物体。最常用于人脸检测。它是由Paul Viola和Michael Jones于2001年提出的。
Haar级联分类器的基本思想是通过组合多个简单的特征来构建一个强大的分类器。这些特征是基于Haar-like特征的概念,它们可以有效地描述图像的局部区域。Haar-like特征是一种基于图像亮度差异的局部特征,可以用于区分人脸和非人脸区域。例如,一个典型的Haar-like特征可以是在图像上的一个矩形区域,该区域的左上部分具有较暗的像素值,而右下部分具有较亮的像素值。
通过使用Haar-like特征,Haar级联分类器可以对图像的不同区域进行特征计算,并将其输入到级联的分类器中进行分类。级联分类器由多个弱分类器组成,每个弱分类器都负责检测特定的特征。级联分类器通过级联地应用这些弱分类器来逐步筛选出可能的人脸区域,最终得到准确的人脸检测结果。
在实际应用中,OpenCV提供了预训练的Haar级联分类器模型,可以用于人脸检测。这些模型通常以XML文件的形式存在,并包含了在大量正负样本上训练得到的分类器参数。可以使用这些预训练的模型来进行人脸检测,而无需自己训练分类器。
要使用Haar级联分类器进行人脸检测,需要加载相应的分类器文件,如haarcascade_frontalface_default.xml,然后将图像转换为灰度图像,并使用detectMultiScale()函数进行人脸检测。
总结来说,Haar级联分类器是一种基于Haar-like特征的人脸检测方法,通过级联的弱分类器来逐步筛选人脸区域。在OpenCV中,可以使用预训练的Haar级联分类器模型进行人脸检测。
Haar级联分类器具有以下优点:
高效性:通过使用Haar特征和级联结构,在处理大量数据时能够快速地减少计算量。
准确性:根据训练数据集得到的多层级联分类器具有高度准确性。
可扩展性:可以通过添加更多的训练数据和调整参数来改进模型性能。
如何训练级联分类器
OpenCV 提供了opencv_createsamples.exe 和opencv_traincascade.exe 文件,这两个 exe 文件可以用来训练级联分类器。
已存在的级联分类器
训练级联分类器很耗时,如果训练的数据量较大,可能需要几天才能完成。OpenCV 提供了一些训练好的级联分类器供用户使用。这些分类器可以用来检测人脸、脸部特征(眼睛、鼻子)、人类和其他物体。这些级联分类器以XML 文件的形式存放在 OpenCV 源文件的 data 目录下,加载不同级联分类器的 XML 文件就可以实现对不同对象的检测。
3.代码实现
python
# coding: utf-8
import cv2
image = cv2.imread('1.jpg')
image = cv2.resize(image, dsize=None, fx=0.1, fy=0.1)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# '''----------------加载分类器----------------'''
faceCascade = cv2.CascadeClassifier('haarcascade_frontalcatface.xml')
# '''----------------分类器检测实现人脸识别----------------'''
# ## objects = cv2.CascadeClassifier.detectMultiScale( image[, scaleFactor
# ## [,minNeighbors[, flags[, minSize[, maxSize]]]]] )
# ## 其中,各个参数及返回值的含义如下。
# ## -image:待检测图像,通常为灰度图像。
# ## -scaleFactor:表示在前后两次相继的扫描中搜索窗口的缩放比例。识别,扫描,按照不同比例来进行扫描
# ## -minNeighbors:表示构成检测目标的相邻矩形的最小个数。在默认情况下,该参数的值为 3,
# ## 表示有 3 个以上的检测标记存在时才认为存在人脸。如果希望提高检测的准确率可以将该参数的值设置得更大,
# ## 但这样做可能会让一些人脸无法被检测到。
# ## flags: 该参数通常被省略。在使用低版本 OpenCV (OpenCV 1.X 版本)时,该参数可能会被设置为
# ## CV_HAAR_DO_CANNY_PRUNING,表示使用 Canny 边缘检测器拒绝一些区域。
# ## -minSize: 目标的最小尺寸,小于这个尺寸的目标将被忽略。
# ## -maxSize: 目标的最大尺寸,大于这个尺寸的目标将被忽略。通常情况下,将该可选参数省略即可。
# ## 若 maxSize 和 minSize 大小一致,则表示仅在一个尺度上查找目标。
# ## -objects: 返回值,目标对象的矩形框向量组。该值是一组矩形信息,
# ## 包含每个检测到的人脸对应的矩形框的信息(x轴方向位置、y轴方向位置、宽度、高度)。
faces = faceCascade.detectMultiScale(gray, scaleFactor=1.03, minNeighbors=10, minSize=(8, 8))
print("发现{}张人脸!".format(len(faces)))
print("其位置分别是:", faces)
'''----------------标注人脸及显示----------------'''
for (x, y, w, h) in faces:
cv2.rectangle(image, pt1=(x, y), pt2=(x + w, y + h), color=(0, 255, 0), thickness=2)
cv2.imshow("result", image)
cv2.waitKey(0)
cv2.destroyAllWindows()
二、微笑检测
微笑检测就是在人脸检测的基础上在进行一次嘴巴都微笑检测,只要嘴巴上扬就会识别出微笑
python
# coding: utf-8
# 人脸微笑检测(摄像头)
import cv2
faceCascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
smile = cv2.CascadeClassifier("haarcascade_smile.xml")
cap = cv2.VideoCapture(0) # 初始化摄像头
while True: # 持续处理每一帧
ret, image = cap.read() # 获取一帧图像,ret表示是否成功获取
image = cv2.flip(image, flipCode=1) # 水平翻转图像(镜像效果)
if ret is None: # 如果没有获取到图像,退出循环
break
# 将彩色图像转为灰度图像(减少计算量,提高检测速度)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
faces = faceCascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=15, minSize=(5, 5)) # 人脸识别
# ---------------------处理每个人脸-----------------------------
for (x, y, w, h) in faces:
cv2.rectangle(image, pt1=(x, y), pt2=(x + w, y + h), color=(0, 255, 0), thickness=2)
# 提取人脸所在区域,多通道形式
# roiColorFace=image[y:y+h,x:x+w]
# 提取人脸所在区域,单通道形式
roi_gray_face = gray[y:y + h, x:x + w]
cv2.imshow('liam', roi_gray_face)
# 微笑检测,仅在人脸区域内检测
smiles = smile.detectMultiScale(roi_gray_face, scaleFactor=1.5, minNeighbors=18, minSize=(50, 50))
for (sx, sy, sw, sh) in smiles:
# 绘制微笑区域
a = x + sx
b = y + sy
cv2.rectangle(image, pt1=(a, b),
pt2=(a + sw, b + sh), color=(255, 0, 0), thickness=2)
# 显示文字"smile"表示微笑了
cv2.putText(image, "smile", (x, y), cv2.FONT_HERSHEY_COMPLEX_SMALL, fontScale=1,
color=(0, 255, 255), thickness=2)
# 显示结果
cv2.imshow('dect', image)
key = cv2.waitKey(25)
if key == 27:
break
cap.release()
cv2.destroyAllWindows()
- 级联分类器是基于 Haar 特征的目标检测方法,需要对应的 XML 模型文件
haarcascade_frontalface_default.xml:用于检测正面人脸haarcascade_smile.xml:用于检测微笑

在cv2库下面的data目录下还有用于其他检测的方法可以自己去尝试一下
