基于Adaboost算法的人脸检测分类器!
共 21248字,需浏览 43分钟
·
2023-09-06 22:59
点击上方“小白学视觉”,选择加"星标"或“置顶”
重磅干货,第一时间送达
人脸检测属于计算机视觉的范畴,早期人们的主要研究方向是人脸识别,即根据人脸来识别人物的身份,后来在复杂背景下的人脸检测需求越来越大,人脸检测也逐渐作为一个单独的研究方向发展起来。
基于知识的方法:主要利用先验知识将人脸看作器官特征的组合,根据眼睛、眉毛、嘴巴、鼻子等器官的特征以及相互之间的几何位置关系来检测人脸。主要包括模板匹配、人脸特征、形状与边缘、纹理特性、颜色特征等方法。
基于统计的方法:将人脸看作一个整体的模式:二维像素矩阵,从统计的观点通过大量人脸图像样本构造人脸模式空间,根据相似度量来判断人脸是否存在。主要包括主成分分析与特征脸、神经网络方法、支持向量机、隐马尔可夫模型、Adaboost算法等。
本文主要基于统计的方法,通过Adaboost算法和Haar特征来构建Haar分类器,对人脸和非人脸进行分类。
本文目录
1. 算法要点
1.1. Haar分类器训练步骤
1.2. Haar的局限性
2. Haar原理解析
2.1. Haar特征
2.2. 积分图构建
2.3. 计算Haar特征值
2.4. Haar特征归一化
2.5. 级联分类器
3. 人脸检测案例
3.1. 人脸检测
3.2. 人脸检测+人眼检测
3.3. 调用摄像头的动态人脸检测
一、算法要点
1.1 Haar分类器训练步骤
Haar分类器=Haar特征+积分图方法+Adaboost+级联。
其训练的五大步骤:
准备人脸、非人脸样本集;
使用Haar特征做检测;
使用积分图(Integral Image)对Haar特征求值进行加速;
使用AdaBoost算法训练区分人脸和非人脸的强分类器;
使用筛选式级联把强分类器级联到一起,提高准确率
具体步骤在第2节中会详细介绍。
1.2 Haar的局限性
仅为人脸检测,非人脸“辩识”,即只能框出人脸的位置,看不出人脸是谁。
仅能标出静态图片和视频帧上的人脸、人眼和微笑,不能进行“活体识别”,即不能看出这张脸是真人还是手机上的照片,如果用于人脸打卡签到、人脸支付的话会带来潜在的安全风险。
仅为普通的机器学习方法,没有用到深度学习和深层神经网络。
二、Haar原理解析
2.1 Haar特征
我们最基础的卷积核(划掉),哦不haar特征为下图中的Basic Haar Set:
我们通常将Haar特征分为以下三类,我们根据名字就可以分辨出这三类的用途:
-
第一类是边缘特征: 第二类是线性特征:
第三类是中心特征:
特征模板内有白色和黑色两种矩形,并定义该模板的特征值为白色矩形像素和减去黑色矩形像素和。Haar特征值反映了图像的灰度变化情况。
例如:脸部的一些特征能由矩形特征简单的描述,如:眼睛要比脸颊颜色要深,鼻梁两侧比鼻梁颜色要深,嘴巴比周围颜色要深等。但矩形特征只对一些简单的图形结构,如边缘、线段较敏感,所以只能描述特定走向(水平、垂直、对角)的结构。由于有时候人脸未必是定向的,可能是会有歪曲的,因此我们可以训练旋转一定角度的矩形特征来识别人脸。
(1)如何快速计算那么多的特征?---积分图大显神通;
(2)哪些矩形特征才是对分类器分类最有效的?---如通过AdaBoost算法来训练。
2.2 积分图构建
2.3.1 矩形特征
以及迭代求解式
2.3.2 旋转矩形特征
对于旋转矩形特征,相应的有 °倾斜积分图用于快速计算Haar特征值,如下图所示,倾斜积分图的定义为像素点左上角 °区域和左下角 °区域的像素和,公式表示如下:
其递推公式计算如下:
也可直接通过下式递归计算:
如下图所示,构建好倾斜积分图后,可快速计算倾斜矩形区域 的像素和值
2.3.3 举个例子
了解了特征值的计算之后,我们来看看不同的特征值的含义是什么。我们选取MIT人脸库中2706个大小为 的人脸正样本图像,计算如下图所示的Haar特征:
左边对应的人眼区域,右边无具体意义。
那么看到这里,应该理解了下面2个问题:
在检测窗口通过平移+缩放可以产生一系列Haar特征,这些特征由于位置和大小不同,分类效果也不同;
-
通过计算Haar特征的特征值,可以有将图像矩阵映射为1维特征值,有效实现了降维。
2.4 Haar特征归一化
计算检测窗口中图像的灰度值和灰度值平方和:
计算平均值:
计算归一化因子:
-
归一化特征值:之后使用归一化的特征值 与阈值对比。
2.5 级联
2.5.1 白话解释
2.5.2 举个例子
6. 一组样本投入强分类器后,在每个渐进的阶段,分类器逐渐在较少的图像窗口上使用更多的特征(负类被丢弃)。如果某个矩形区域在所有弱分类器中都被归结为正类,那么可以认为该区域是存在人脸的。
其中,弱分类器训练的具体步骤如下:
1. 对于每个特征 ,计算所有训练样本的特征值,并将其排序:
2. 扫描一遍排好序的特征值,对排好序的表中的每个元素,计算下面四个值:
计算全部正例的权重和 ;
计算全部负例的权重和 ;
计算该元素前之前的正例的权重和 ;
计算该元素前之前的负例的权重和
三、人脸检测例子
3.1 人脸检测
执行以下代码,即可获得人脸检测的结果:
img = cv2.imread("Pic/1.jpg")
face_engine = cv2.CascadeClassifier(cv2.data.haarcascades+'haarcascade_frontalface_default.xml')
faces = face_engine.detectMultiScale(img,scaleFactor=1.3,minNeighbors=5)
for (x,y,w,h) in faces:
img = cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
cv2.imshow('img',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
我们留意到以上代码的face_engine步骤,其作用是导入人脸级联分类器引擎,'.xml'文件里包含训练出来的人脸特征。随后用人脸级联分类器引擎进行人脸识别,返回的faces为人脸坐标列表,1.3是放大比例,5是重复识别次数。
3.2 人脸检测和人眼检测
我们也可以尝试前面xml文件中的人眼检测:
#导入opencv
import cv2
# 导入人脸级联分类器引擎,'.xml'文件里包含训练出来的人脸特征,cv2.data.haarcascades即为存放所有级联分类器模型文件的目录
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades+'haarcascade_frontalface_default.xml')
# 导入人眼级联分类器引擎吗,'.xml'文件里包含训练出来的人眼特征
eye_cascade = cv2.CascadeClassifier(cv2.data.haarcascades+'haarcascade_eye.xml')
# 读入一张图片,引号里为图片的路径,需要你自己手动设置
img = cv2.imread('image3.png')
# 用人脸级联分类器引擎进行人脸识别,返回的faces为人脸坐标列表,1.3是放大比例,5是重复识别次数
faces = face_cascade.detectMultiScale(img, 1.3, 5)
# 对每一张脸,进行如下操作
for (x,y,w,h) in faces:
# 画出人脸框,蓝色(BGR色彩体系),画笔宽度为2
img = cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
# 框选出人脸区域,在人脸区域而不是全图中进行人眼检测,节省计算资源
face_area = img[y:y+h, x:x+w]
eyes = eye_cascade.detectMultiScale(face_area)
# 用人眼级联分类器引擎在人脸区域进行人眼识别,返回的eyes为眼睛坐标列表
for (ex,ey,ew,eh) in eyes:
#画出人眼框,绿色,画笔宽度为1
cv2.rectangle(face_area,(ex,ey),(ex+ew,ey+eh),(0,255,0),1)
# 在"img2"窗口中展示效果图
cv2.imshow('img2',img)
# 监听键盘上任何按键,如有案件即退出并关闭窗口,并将图片保存为output.jpg
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.imwrite('output.jpg',img)
上面的代码最值得注意的就是face_area = img[y:y+h, x:x+w],这一步会将人脸区域框出来,在其中执行人眼检测。同样对上图进行检测,结果如下:
3.3 调用电脑摄像头进行实时人脸识别和人眼识别
import cv2
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades+'haarcascade_frontalface_default.xml')
eye_cascade = cv2.CascadeClassifier(cv2.data.haarcascades+'haarcascade_eye.xml')
# 调用摄像头摄像头
cap = cv2.VideoCapture(0)
while(True):
# 获取摄像头拍摄到的画面
ret, frame = cap.read()
faces = face_cascade.detectMultiScale(frame, 1.3, 5)
img = frame
for (x,y,w,h) in faces:
# 画出人脸框,蓝色,画笔宽度微
img = cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
# 框选出人脸区域,在人脸区域而不是全图中进行人眼检测,节省计算资源
face_area = img[y:y+h, x:x+w]
eyes = eye_cascade.detectMultiScale(face_area)
# 用人眼级联分类器引擎在人脸区域进行人眼识别,返回的eyes为眼睛坐标列表
for (ex,ey,ew,eh) in eyes:
#画出人眼框,绿色,画笔宽度为1
cv2.rectangle(face_area,(ex,ey),(ex+ew,ey+eh),(0,255,0),1)
# 实时展示效果画面
cv2.imshow('frame2',img)
# 每5毫秒监听一次键盘动作
if cv2.waitKey(5) & 0xFF == ord('q'):
break
# 最后,关闭所有窗口
cap.release()
cv2.destroyAllWindows()
下载1:OpenCV-Contrib扩展模块中文版教程
在「小白学视觉」公众号后台回复:扩展模块中文教程,即可下载全网第一份OpenCV扩展模块教程中文版,涵盖扩展模块安装、SFM算法、立体视觉、目标跟踪、生物视觉、超分辨率处理等二十多章内容。
下载2:Python视觉实战项目52讲 在「小白学视觉」公众号后台回复:Python视觉实战项目,即可下载包括图像分割、口罩检测、车道线检测、车辆计数、添加眼线、车牌识别、字符识别、情绪检测、文本内容提取、面部识别等31个视觉实战项目,助力快速学校计算机视觉。
下载3:OpenCV实战项目20讲 在「小白学视觉」公众号后台回复:OpenCV实战项目20讲,即可下载含有20个基于OpenCV实现20个实战项目,实现OpenCV学习进阶。
交流群
欢迎加入公众号读者群一起和同行交流,目前有SLAM、三维视觉、传感器、自动驾驶、计算摄影、检测、分割、识别、医学影像、GAN、算法竞赛等微信群(以后会逐渐细分),请扫描下面微信号加群,备注:”昵称+学校/公司+研究方向“,例如:”张三 + 上海交大 + 视觉SLAM“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进入相关微信群。请勿在群内发送广告,否则会请出群,谢谢理解~