Viola Jones检测器由三个核心步骤组成,即Haar-like特征和积分图、Adaboost分类器以及级联分类器。假设在目标检测时,需要这么一个子窗口,在待检测的图像中不断的滑位移动,子窗口每到一个位置,就会计算出该区域的特征,然后用训练好的级联分类器对该特征进行筛选,只要该特征通过了所有强分类器的筛选,则判定该区域为目标区域。
如图9.3所示,是5种不同的Haar-like特征算子,假设各个图片中的黑色区域灰度值总和为ℎ,白色区域灰度值总和为𝑏,ℎ − 𝑏得到的结果即子窗口区域的Haar-like特征值。
图 9.3 haar特征
矩形特征可位于图像窗口的任意位置,其大小也可以任意改变,所以矩形特征值是haar特征算子类别、矩形位置和矩形大小这三个因素的所决定的. 故类别、大小、位置的变化,使得较小的图片也会包含很多的矩形特征.。
以一个24 × 24 的窗口为例,采用图9.3的5种不同的Haar-like特征算子进行计算,五种Haar-like特征算子的特征值数量分别为:43200,43200,27600,27600,20736,总计为160381. 就单单24 × 24 大小的图像窗口就有16万以上的特征值,现在,面临着两个问题:
- 面对这么多的特征值数量,该如何优化计算,减少计算量呢?
- 特征值的数量太多,肯定有一些特征值对于识别正样本与负样本较好,有一些不能够较好区分正样本与负样本. 那该怎么找到这些好的,优秀的特征即最优弱分类器。
首先解决第一个问题,需要用到积分图,对于一幅灰度图,积分图中的任意一点的值是从原图像的左上角到这个点所构成的矩形区域内的所有点的灰度值之和,如图9.4所示:左图为原图,右图为积分图,积分图中的第3行第4列就是原图中黄色方框区域的像素和,积分图中的第5行第2列为原图像中紫色方框区域的像素和。
图 9.4 积分图
如图9.4所示的公式可以构建积分图,但一般是用下面的公式来进行积分图的构建:
- 表示图像第i行前j个像素值累加和,初始化
- 用表示一个积分图像,初始化
- 逐行扫描图像,计算每个像素ii,j的累加和的值,计算方法分别如下式:
- 扫描图像一遍,当到达图像右下角像素时,积分图ii(i,j)构建完毕。如何通过积分图来计算图像某一矩形区域内的像素和?
如图9.5所示:原图像中,有A,B,C,D四块区域,其中a,b,c,d表示D区域的四个顶点。怎么计算出D区域的积分图呢?
图 9.5 图像区域
用,,,分别表示图9.5中的a,b,c,d四个点的积分值。利用下面式9.3计算区域D内像素的总灰度值得:
根据上面的理论,可以发现,积分图技术引入后,图像的Haar-like矩形特征值只受其所对应的积分图的值的影响,图像所在位置坐标的变化与其值没有关联。这样在计算矩形特征的时候就可以缩短计算特征值所耗费的时长。
训练最优弱分类器现在来解决第二个问题,特征数量太多,需要进行特征的筛选,选择最优弱分类器。最初的弱分类器可能只是一个最基本的Haar-like特征,计算输入图像的Haar-like特征值,和最初的弱分类器的特征值比较,来判断输入图像是否为人脸,然而这个弱分类器太简陋了,可能不比随机判断的效果好,对弱分类器的孵化就是训练弱分类器为最优分类器,注意这是的最优不是强分类器,只是一个误差相对稍低的弱分类器,训练弱分类器实际上是为分类器进行设置的过程. 至于如何设置分类器,设置什么,先来看下弱分类器的数学结构如下式9.4所示:
其中的参数x为特征窗口,p代表着不等式的不同方向,取值为1和-1,g为矩形窗口所对应的Haar-like特征值,θ为弱分类器的判断阈值。
最基本的弱分类器只包含一个Haar-like特征,也就是说决策树只有一层,被称为树桩(stump)。要比较输入图像的特征值和弱分类器特征,需要一个阈值,当输入图像的特征值大于该阈值时判定其为人脸。训练最优弱分类器的过程其实就是在寻找合适的分类器阈值,使该分类器对所有样本的判断误差最低,具体 *** 作过程如下:
寻找使分类误差最小的最优阈值,有了该阈值,第一个最优弱分类器就诞生了,第一个最优弱分类器的诞生,意味着筛选出了一个最好的Haar-like特征值。
训练强分类器弱分类只是具有一定分类能力的分类器,其比并不能达到对分类器的基本要求,所以需要对其进行进一步加强,构建基于弱分类器的强分类器。具体的训练步骤如下:
- 对样本训练集进行初始化
训练样本集(x1,y1),…,(xn,yn),其中yi∈0,1, yi是正负样本标识,1为正,否则为负。
- 根据正负样本数初始化样本权重
正样本初始权重为,负样本初始权重为,其中m,l是人脸样本总数和非人脸样本总数,所有样本的总数为n,且满足n=m+l的条件,用来表示权重,其中t指的是第t次的算法迭代,j指的是训练样本中的第j个
- 弱分类器的迭代训练
强分类器
最后的强分类器记为:
其中,表示最高训练次数。
级联分类器通过上述AdaBoost算法训练可以构建出一个强分类器,但是这样的分类器精确度还是有待提高,所以强分类器并不是分类器最后的结构,为了使得分类器的精确度与检测效率更加出色,可以使用级联方法将强分类器组合成级联分类器。
图 9.6 级联分类器
实际上,训练级联分类器的目的就是为检测时更加准确,Haar分类器的检测体系是以现实中的一幅图像作为输入,然后对图像中进行多区域,多尺度的检测. 所谓的多区域,是对图像划分多块,对每个块进行检测。
由于训练时用的照片只有20 * 20左右的小图像,所以对于大的人脸,还需要进行多尺度的检测,多尺度检测机制一般有两种策略,一种是不改变搜索窗口的大小,而不断缩放图像,这种方法需要对每个缩放后的图像进行区域特征值的运算,效率不高。
另一种方法,是不断初始化搜索窗口大小为训练时的图片大小,不断扩大搜索窗口,进行搜索,解决了第一种方法的弱势。在区域放大的过程中会出现同一个人脸会被多次检测,这需要进行区域的合并。无论哪一种搜索方法,都会为输入图像输出大量的子窗口,这些子窗口经过筛选式级联分类器会不断被第一个节点筛选,抛弃或通过,如图9.6所示。
用opencv提供的Viola Jones分类器实现人脸,人眼的检测,其实现代码如下:
import cv2
#加载分类器
eye_cascade=cv2.CascadeClassifier(cv2.data.haarcascades,'haarcascade_eye.xml')
img=cv2.imread('image/lenna.bmp') #加载检测图片
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
#通过分类器对图片进行目标检测
eyes=eye_cascade.detectMultiScale(gray,scaleFactor=1.3,minNeighbors=5)
#标注眼睛所在区域
for (x, y, w, h) in eyes:
img=cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.imshow('demo', img) #输出显示
cv2.waitKey(0)
图 9.7 运行结果
如上所示,opencv已经包含了很多已经训练好的分类器,其中包括:面部,眼睛,微笑等。在python中的调用训练好的级联分类器所用到的函数如下:
cv2.CascadeClassifier(cv2.data.haarcascades,'haarcascade_eye.xml'):其中调用时的参数主要有分类器的类别,haarcascade_eye.xml是opencv已经训练好的检测人眼的级联分类器,其他常用的分类如下表9.1:
表 9.1 级联分类器
人脸检测器(默认) | haarcascade_frontalface_default.xml |
人脸检测器(快速Harr) | haarcascade_frontalface_alt2.xml |
人脸检测器(侧视) | haarcascade_profileface.xml |
眼部检测器(左眼) | haarcascade_lefteye_2splits.xml |
眼部检测器(右眼) | haarcascade_righteye_2splits.xml |
嘴部检测器 | haarcascade_mcs_mouth.xml |
鼻子检测器 | haarcascade_mcs_nose.xml |
身体检测器 | haarcascade_fullbody.xml |
detectMultiScale(image,scaleFactor = 1.1,minNeighbors = 3 ):其中image为待检测的灰度图像, scaleFactor为前后两次相继的扫描中搜索窗口的比例系数,默认为1.1 即每次搜索窗口扩大10%,minNeighbors 为构成检测目标的相邻矩形的最小个数,如果组成检测目标的小矩形的个数和小于minneighbors - 1 都会被排除
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)