郴州市兴旺宝明通网络有限公司
首页 | 联系方式 | 加入收藏 | 设为首页 | 手机站

产品目录

联系方式

联系人:业务部
电话: 00144-186681728
邮箱:service@tjzhuojun.com

当前位置:首页 >> 新闻中心 >> 正文

1-Haar特征的特点及计算

字号:
摘要:1-Haar特征的特点及计算

1.Haar特征

最早的Haar特征由PapageorgiouC.等提出(《A general framework for object detection》),后来PaulViola和Michal Jones提出利用积分图像法快速计算Haar特征的方法(《Rapid object detection using a boosted cascade of simplefeatures》)。之后,Rainer Lienhart 和 Jochen Maydt用对角特征对Haar特征库进行了扩展(《An extended set of Haar-like features for rapid objectdetection》)。OpenCV的Haar分类器就是基于扩展后的特征库(含下图中的1、2、3,共14种)实现的。

1.1 Haar特征定义

Haar特征是基于“块”的特征,也被称为矩形特征。Haar特征(模板)分为三类:边缘特征、线性特征、中心特征和对角线特征。特征模板内有白色和黑色两种矩形,并定义该模板的特征值为白色矩形像素和减去黑色矩形像素和。Haar特征值反映了图像的灰度变化情况。例如:脸部的一些特征能由矩形特征简单的描述,如:眼睛要比脸颊颜色要深,鼻梁两侧比鼻梁颜色要深,嘴巴比周围颜色要深等。但矩形特征只对一些简单的图形结构,如边缘、线段较敏感,所以只能描述特定走向(水平、垂直、对角)的结构。

对于图中的1.a这类特征,特征数值计算公式为:v=Sum白-Sum黑,而对于2.c这类来说,计算公式如下:v=Sum白-2*Sum黑;之所以将黑色区域像素和乘以2,是为了使两种矩形区域中像素数目一致。


1.2 Haar特征的数量
通过改变特征模板的大小和位置,可在图像子窗口中穷举出大量的特征。上图的特征模板称为“特征原型”;特征原型在图像子窗口中扩展(平移伸缩)得到的特征称为“矩形特征”;矩形特征的值称为“特征值”。
矩形特征可位于图像任意位置,大小也可以任意改变,所以矩形特征值是矩形模版类别、矩形位置和矩形大小这三个因素的函数。故类别、大小和位置的变化,使得很小的检测窗口含有非常多的矩形特征。对于一个给定的24X24的窗口,根据不同的位置,以及不同的缩放,可以产生超过160,000个特征,因此计算一幅图像的所有Haar特征是一件工作量很大的事。


具体的计算Haar特征个数的公式为Rainer Lienhart提出的:

具体的推导过程可参考:

【图像处理】计算Haar特征个数:http://blog.csdn.net/xiaowei_cqu/article/details/8216109

计算Haar特征个数:http://blog.csdn.net/wangli071125/article/details/9083517


1.3 Haar特征的快速计算-积分图

通过一次遍历图像得到“积分图”(Integralimage),也叫Summed Area Table,之后任何一个Haar矩形特征都可以通过查表的方法(Look Up Table)和有限次简单运算得到,大大减少了运算次数。

原图像A经过“积分”后得到相同大小的图像B,B中(x,y)处的值B(x,y)是原图像(x,y)位置左上角方向所有像素的和,即:



举例:


得到图像的积分图后,特征模板的Haar特征值就很好求了。举例如下:

红色矩形为特征模板,矩形中白色区域像素和为B(5)+B(1)-B(2)-B(6),矩形中黑色区域像素和为B(4)+B(2)-B(3)-B(5)。二者作差即可得特征值。

此外,对于对角线矩形特征模板,需要构建旋转积分图像。具体可参考:

利用积分图像法快速计算Haar特征:http://blog.csdn.net/xiaowei_cqu/article/details/8219324

积分图构建采用增量算法:

1)用s(i,j)表示行方向的累加和,初始化s(i,-1)=0;

2)用ii(i,j)表示一个积分图像,初始化ii(-1,i)=0;

3)逐行扫描图像,递归计算每个像素(i,j)行方向的累加和s(i,j)和积分图像ii(i,j)的值

s(i,j)=s(i,j-1)+f(i,j)

ii(i,j)=ii(i-1,j)+s(i,j)

4)扫描图像一遍,当到达图像右下角像素时,积分图像ii就构造好了。


下面给出的代码是MATLAB 调用.C文件来计算积分图(for循环较多,C语言会快很多)

(关于MATLAB调用.C和.CPP文件,可以参考我的博文:MATLAB调用编译.C和.CPP文件)

#include 
#include "mex.h"
// compute integral img
// s(i,j) = s(i-1,j)+i(i,j)
// ii(i,j) = ii(i,j-1)+s(i,j)
// s(i,j) = s(i+j*M);
// s(0,j) = i(0,j);ii(i,0)=s(i,0)
/* Input Arguments */
#define img_IN prhs[0]
/* Output Arguments */
#define ii_OUT plhs[0]
/*ii为输出积分图,img为输入原图像,M为行,N为列*/
static void integral(
 double ii[],
 double *img,
 int M,
 int N)
{
 int i;
 int j;
 double *s = new double[M*N];
/*列累积*/
 for(j=0; j