主要有两大类:基于知识和基于统计。
基于知识的方法主要利用先验知识将人脸看作器官特征的组合,根据眼睛、眉毛、嘴巴、鼻子等器官的特征以及相互之间的几何位置关系来检测人脸。
基于统计的方法则将人脸看作一个整体的模式——二维像素矩阵,从统计的观点通过大量人脸图像样本构造人脸模式空间,根据相似度量来判断人脸是否存在。
基于知识的人脸检测方法
Ø 模板匹配
Ø 人脸特征
Ø 形状与边缘
Ø 纹理特性
Ø 颜色特征
基于统计的人脸检测方法
Ø 主成分分析与特征脸
Ø 神经网络方法
Ø 支持向量机
Ø 隐马尔可夫模型
Ø Adaboost算法
分类器,在这里就是指对人脸和非人脸进行分类的算法,在机器学习领域,很多算法都是对事物进行分类、聚类的过程。
聚类和分类的区别是什么?
一般对已知物体类别总数的识别方式我们称之为分类,并且训练的数据是有标签的,比如已经明确指定了是人脸还是非人脸,这是一种有监督学习。
处理类别总数不确定的方法或者训练的数据是没有标签的,这就是聚类,不需要学习阶段中关于物体类别的信息,是一种无监督学习。
Haar分类器实际上是Boosting算法的一个应用,Haar分类器用到了Boosting算法中的AdaBoost算法,只是把AdaBoost算法训练出的强分类器进行了级联,并且在底层的特征提取中采用了高效率的矩形特征和积分图方法。
Haar分类器算法的要点如下:
① 使用Haar-like特征做检测。
② 使用积分图(Integral Image)对Haar-like特征求值进行加速。
③ 使用AdaBoost算法训练区分人脸和非人脸的强分类器。
④ 使用筛选式级联把强分类器级联到一起,提高准确率。
(1)Haar-like特征
假设在人脸检测时我们需要有这么一个子窗口在待检测的图片窗口中不断的移位滑动,子窗口每到一个位置,就会计算出该区域的特征,然后用我们训练好的级联分类器对该特征进行筛选,一旦该特征通过了所有强分类器的筛选,则判定该区域为人脸。
· 那么这个特征如何表示呢?好了,这就是大牛们干的好事了。后人称这他们搞出来的这些东西叫Haar-Like特征。
下面是Viola牛们提出的Haar-like特征。
下面是Lienhart等牛们提出的Haar-like特征。
将上面的任意一个矩形放到人脸区域上,然后,将白色区域的像素和减去黑色区域的像素和,得到的值我们暂且称之为人脸特征值,如果你把这个矩形放到一个非人脸区域,那么计算出的特征值应该和人脸特征值是不一样的,而且越不一样越好,所以这些方块的目的就是把人脸特征量化,以区分人脸和非人脸。
为了增加区分度,可以对多个矩形特征计算得到一个区分度更大的特征值,那么什么样的矩形特征怎么样的组合到一块可以更好的区分出人脸和非人脸呢,这就是AdaBoost算法做的事。
(2)积分图是一个加速器
Haar-like分类器的训练和检测过程,无论是训练还是检测,每遇到一个图片样本,每遇到一个子窗口图像,我们都面临着如何计算当前子图像特征值的问题,一个Haar-like特征在一个窗口中怎样排列能够更好的体现人脸的特征,这是未知的,所以才要训练,而训练之前我们只能通过排列组合穷举所有这样的特征,仅以Viola牛提出的最基本四个特征为例,在一个24×24size的窗口中任意排列至少可以产生数以10万计的特征,对这些特征求值的计算量是非常大的。
而积分图就是只遍历一次图像就可以求出图像中所有区域像素和的快速算法,大大的提高了图像特征值计算的效率。
(3)AdaBoost算法
AdaBoost的老祖宗可以说是机器学习的一个模型,它的名字叫PAC(Probably Approximately Correct)。
# 1.导入库
import cv2
# 2.方法:绘制图片中检测到的人脸
def draw_face(img,faces):
for (x, y, w, h) in faces:
# 画出人脸框,蓝色(BGR色彩体系),画笔宽度为2
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 2)
# 3.主函数:
if __name__ == "__main__":
# 4.读取一张照片
img=cv2.imread('img_1.jpg')
cv2.imshow('face', img)
# 5.转换成灰度图
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# 6.通过opencv加载haar级联分类器
face_alt2 = cv2.CascadeClassifier(cv2.data.haarcascades+'haarcascade_frontalface_alt2.xml')
# 7.对图像中的人脸进行检测
face_alt2_detect_faces = face_alt2.detectMultiScale(img,scaleFactor=1.3,minNeighbors=5)
# 8.绘制图片中检测到的人脸
draw_face(img,face_alt2_detect_faces)
# 9.显示照片
cv2.imshow('face',img)
# 10.关闭窗口
cv2.waitKey(0)
cv2.destroyAllWindows()
测试结果:
结果对比,也可以发现该方法仅支持正面的人脸检测,效果不佳。
更多人脸检测参考:
# 1.导入库
import cv2
# 2.方法:绘制图片中检测到的人脸
def draw_face(img,faces):
for (x, y, w, h) in faces:
# 画出人脸框,蓝色(BGR色彩体系),画笔宽度为2
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 2)
# 3.主函数:
if __name__ == "__main__":
# 4.读取摄像头
capture=cv2.VideoCapture(0)
while (True):
ret, frame = capture.read()
# 5.通过opencv加载haar级联分类器
face_alt2 = cv2.CascadeClassifier(cv2.data.haarcascades+'haarcascade_frontalface_alt2.xml')
# 6.对图像中的人脸进行检测
face_alt2_detect_faces = face_alt2.detectMultiScale(frame,scaleFactor=1.3,minNeighbors=5)
# 7.绘制图片中检测到的人脸
draw_face(frame,face_alt2_detect_faces)
# 8.实时展示效果画面
cv2.imshow('face', frame)
# 每5毫秒监听一次键盘动作
if cv2.waitKey(5) & 0xFF == ord('q'):
break
# 8.关闭窗口
cv2.waitKey(0)
cv2.destroyAllWindows()
结果显示:
运行起来就会觉得HAAR的识别效果不怎么样,稍微动一下就很会识别不了。
参考:
浅析人脸检测之Haar分类器方法 - ello - 博客园
第九节、人脸检测之Haar分类器 - 大奥特曼打小怪兽 - 博客园