Haar特征原理与icvCreateIntHaarFeatures方法的具体实现附详细注释—— 人脸识别的尝试系列(二)

来源:互联网 发布:mysql 登录失败设置 编辑:程序博客网 时间:2024/06/05 15:58

带着强烈的兴趣,上周开始人脸识别的尝试与学习,并且将具体的操作过程记录了下来

链接如下:http://blog.csdn.net/u011583927/article/details/44627493

这周开始了对于算法的深入学习,下面进入正题。


Haar特征的原理是什么?

Haar特征分为三类:边缘特征、线性特征、中心特征和对角线特征,组合成特征模板。特征模板内有白色和黑色两种矩形,并定义该模板的特征值为白色矩形像素和减去黑色矩形像素和(在opencv实现中为黑色-白色)。Haar特征值反映了图像的灰度变化情况。例如:脸部的一些特征能由矩形特征简单的描述,如:眼睛要比脸颊颜色要深,鼻梁两侧比鼻梁颜色要深,嘴巴比周围颜色要深等。但矩形特征只对一些简单的图形结构,如边缘、线段较敏感,所以只能描述特定走向(水平、垂直、对角)的结构。(本段文字及下面两幅图引用自http://blog.csdn.net/zouxy09/article/details/7929570)

Viola提出的haar特征:

 

Lienhart等牛们提出的Haar-like特征:

 

矩形特征可位于图像任意位置,大小也可以任意改变,所以矩形特征值是矩形模版类别、矩形位置和矩形大小这三个因素的函数,当然对于新提出的有旋转角度的haar特征,还要把旋转的因素考虑进去。

所以一个Haar特征的数据结构应该包含以下内容: 

*haar特征模板类型

*是否有旋转

*矩阵位置及大小

 

CvIntHaarFeatures是如何构成的?

Opencv中,我们用CvTHaarFeatureCvFastHaarFeature作为描述单个特征的数据结构,用CvIntHaarFeatures作为一个封装的类型,通过这个类型中的两个指针(分别是CvTHaarFeature*CvFastHaarFeature*指针)可以间接遍寻到存储的所有的特征。下面来看下它们的具体构造


CvTHaarFeature的数据结构:

//CvTHaarFeature:由(至多三个)矩形表示特征位置

typedef struct CvTHaarFeature

{

    char desc[CV_HAAR_FEATURE_DESC_MAX];   //描述haar特征模板类型的变量

    int  tilted; //标识是否有旋转,通过desc字符数组开头是否为tilted判断

    struct

    {

        CvRect r;

        float weight;

    } rect[CV_HAAR_FEATURE_MAX];            //三个矩形来描述特征位置

} CvTHaarFeature;

 

 

创建一个CvTHaarFeature特征:

/*例:haarFeature = cvHaarFeature("tilted_haar_y2",

                                    x, y, dx,2*dy, -1,

                                    x, y,dx,   dy, +2 );*/

CV_INLINECvTHaarFeature cvHaarFeature(constchar* desc,

                            int x0, int y0, int w0,int h0,float wt0,

                            int x1, int y1, int w1,int h1,float wt1,

                            int x2, int y2, int w2,int h2,float wt2 )

{

    CvTHaarFeature hf;

 

    assert( CV_HAAR_FEATURE_MAX >= 3 );

    assert( strlen( desc ) <CV_HAAR_FEATURE_DESC_MAX );

 

    strcpy( &(hf.desc[0]), desc );

    hf.tilted = ( hf.desc[0] == 't' );

 

    hf.rect[0].r.x = x0;

    hf.rect[0].r.y = y0;

    hf.rect[0].r.width  = w0;

    hf.rect[0].r.height = h0;

    hf.rect[0].weight   = wt0;

 

    hf.rect[1].r.x = x1;

    hf.rect[1].r.y = y1;

    hf.rect[1].r.width  = w1;

    hf.rect[1].r.height = h1;

    hf.rect[1].weight   = wt1;

 

    hf.rect[2].r.x = x2;

    hf.rect[2].r.y = y2;

    hf.rect[2].r.width  = w2;

    hf.rect[2].r.height = h2;

    hf.rect[2].weight   = wt2;

 

    return hf;

}

 

 

CvFastHaarFeature的数据结构:

//CvTHaarFeature类似,不同的是通过4个点来描述特征矩形的位置大小信息

typedef struct CvFastHaarFeature

{

    int tilted;

    struct

    {

        int p0, p1, p2, p3;

        float weight;

    } rect[CV_HAAR_FEATURE_MAX];

} CvFastHaarFeature;

 

CvIntHaarFeatures的数据结构:

typedef struct CvIntHaarFeatures

{

    CvSize winsize;

    int count;

    CvTHaarFeature* feature;

    CvFastHaarFeature* fastfeature;

} CvIntHaarFeatures;


了解了如何构成,我们就来创建,icvCreateIntHaarFeatures()方法的具体实现:

接下来就是最重要的一步,如何创建我们想要得到的所有特征信息及CvIntHaarFeatures,下面是icvCreateIntHaarFeatures方法的具体实现和详细注释

由于opencv和C++都是初学,用了很长时间写了大量注释,0基础也绝对能看懂,希望能对大家有帮助



由于我是小白,感觉上面代码中的最后几行逻辑可能比较绕,卡在那里好久终于理解。

所以做了一张图,可以借助下图帮助理解


<span style="font-family: Arial, Helvetica, sans-serif;">看到这里,对于Haar特征的理论以及实际使用应该理解的不错了吧,希望能和大家一起交流</span>





0 0
原创粉丝点击