icvCreateIntHaarFeatures超详细解析(不看你会后悔的)

本博是笔者读书笔记整理,欢迎转载,请注明出处,如有不足,还望网友们指教。

/*
 * icvCreateIntHaarFeatures
 *
 * Create internal representation of haar features
 *
 * mode:
 *  0 - BASIC = Viola
 *  1 - CORE  = All upright
 *  2 - ALL   = All features
 */
//功能:针对大小为winsize的图像,计算所有的HaarFeature的rect,并存入features 返回输入
static
CvIntHaarFeatures* icvCreateIntHaarFeatures( CvSize winsize,
                                             int mode,
											 /*
	   mode=0,只计算如下6种特征haar_x2,haar_y2,haar_x3,haar_y3,haar_y4,haar_x2_y2
       mode=1,只计算如下8种特征haar_x2,haar_y2,haar_x3,haar_y3,haar_x4,haar_y4,haar_point
       mode=2,计算所以特征,如下:haar_x2,haar_y2,haar_x3,haar_y3,haar_x4,haar_y4,haar_point,tilted_haar_x2,tilted_haar_y2,
                                  tilted_haar_x3,tilted_haar_y3,tilted_haar_x4,tilted_haar_y4。*/
                                             int symmetric )/*表示目标图形是否为垂直对称.Symmetric 为 1 
表示只创建 Haar 特征的中心在左半部分的所有特征,为 0 时创建所有特征。当训练人脸图像时,由于人脸的左右对称性可以设置 Symmetric 为 1,以加速训练。 */
{
    CvIntHaarFeatures* features = NULL;//存储所有Haar特征的结构体,Haar特征由指针CvTHaarFeature所指向。
    CvTHaarFeature haarFeature;        //一个Haar特征由2到3个具有相应权重的矩形组成。
                                       //这几个矩形的权重符号相反,并且权重的绝对值跟矩形的大小成反比。
	/*内存存储器是一个可用来存储诸如序列,轮廓,图形,子划分等动态增长数据结构的底层结构。
	它是由一系列以同等大小的内存块构成,呈列表型,本句选自https://code.csdn.net/snippets/632568/master/.cpp/raw*/
    CvMemStorage* storage = NULL;
    CvSeq* seq = NULL;
    CvSeqWriter writer;

    int s0 = 36; /* minimum total area size of basic haar feature     */
    int s1 = 12; /* minimum total area size of tilted haar features 2 */
    int s2 = 18; /* minimum total area size of tilted haar features 3 */
    int s3 = 24; /* minimum total area size of tilted haar features 4 */

    int x  = 0;
    int y  = 0;    //(x,y)表示小矩形的位置
    int dx = 0;    //dx表示小矩形的宽
    int dy = 0;    //dy表示小矩形的高
///
	//计算缩放因子factor
	//winsize是训练样本的大小
#if 0
    float factor = 1.0F;

    factor = ((float) winsize.width) * winsize.height / (24 * 24);

    s0 = (int) (s0 * factor);
    s1 = (int) (s1 * factor);
    s2 = (int) (s2 * factor);
    s3 = (int) (s3 * factor);
#else
    s0 = 1;
    s1 = 1;
    s2 = 1;
    s3 = 1;
#endif

    /* CV_VECTOR_CREATE( vec, CvIntHaarFeature, size, maxsize ) */
    storage = cvCreateMemStorage();
	//功能:创建新序列,并初始化写入部分
    cvStartWriteSeq( 0, sizeof( CvSeq ), sizeof( haarFeature ), storage, &writer );
    for( x = 0; x < winsize.width; x++ )
    {
        for( y = 0; y < winsize.height; y++ )
        {
            for( dx = 1; dx <= winsize.width; dx++ )
            {
                for( dy = 1; dy <= winsize.height; dy++ )
                {
                    // haar_x2
                    if ( (x+dx*2 <= winsize.width) && (y+dy <= winsize.height) ) {
                        if (dx*2*dy < s0) continue;///?????????????????????
                        if (!symmetric || (x+x+dx*2 <=winsize.width)) {
                            haarFeature = cvHaarFeature( "haar_x2",//类型
                                x,    y, dx*2, dy, -1,             //[x,y,dx*2,dy]是一个小矩形左上角的位置和高和宽,-1是其权重
                                x+dx, y, dx  , dy, +2 );           //[x,y,dx*2,dy]是一个小矩形左上角的位置和高和宽,2是其权重
	             			//第一个小矩形中的像素和乘以-1,然后加上第二个小矩形的像素和乘以2,也就是水平方向上两个等宽的小矩形,用右边的减去左边的
                            /* CV_VECTOR_PUSH( vec, CvIntHaarFeature, haarFeature, size, maxsize, step ) */
                            CV_WRITE_SEQ_ELEM( haarFeature, writer );
                        }
                    }

                    // haar_y2
                    if ( (x+dx <= winsize.width) && (y+dy*2 <= winsize.height) ) {
                        if (dx*2*dy < s0) continue;
                        if (!symmetric || (x+x+dx <= winsize.width)) {
                            haarFeature = cvHaarFeature( "haar_y2",
                                x, y,    dx, dy*2, -1,
                                x, y+dy, dx, dy,   +2 );
                            CV_WRITE_SEQ_ELEM( haarFeature, writer );
                        }
                    }

                    // haar_x3
                    if ( (x+dx*3 <= winsize.width) && (y+dy <= winsize.height) ) {
                        if (dx*3*dy < s0) continue;
                        if (!symmetric || (x+x+dx*3 <=winsize.width)) {
                            haarFeature = cvHaarFeature( "haar_x3",
                                x,    y, dx*3, dy, -1,
                                x+dx, y, dx,   dy, +3 );
                            CV_WRITE_SEQ_ELEM( haarFeature, writer );
                        }
                    }

                    // haar_y3
                    if ( (x+dx <= winsize.width) && (y+dy*3 <= winsize.height) ) {
                        if (dx*3*dy < s0) continue;
                        if (!symmetric || (x+x+dx <= winsize.width)) {
                            haarFeature = cvHaarFeature( "haar_y3",
                                x, y,    dx, dy*3, -1,
                                x, y+dy, dx, dy,   +3 );
                            CV_WRITE_SEQ_ELEM( haarFeature, writer );
                        }
                    }

                    if( mode != 0 /*BASIC*/ ) {
                        // haar_x4
                        if ( (x+dx*4 <= winsize.width) && (y+dy <= winsize.height) ) {
                            if (dx*4*dy < s0) continue;
                            if (!symmetric || (x+x+dx*4 <=winsize.width)) {
                                haarFeature = cvHaarFeature( "haar_x4",
                                    x,    y, dx*4, dy, -1,
                                    x+dx, y, dx*2, dy, +2 );
                                CV_WRITE_SEQ_ELEM( haarFeature, writer );
                            }
                        }

                        // haar_y4
                        if ( (x+dx <= winsize.width ) && (y+dy*4 <= winsize.height) ) {
                            if (dx*4*dy < s0) continue;
                            if (!symmetric || (x+x+dx   <=winsize.width)) {
                                haarFeature = cvHaarFeature( "haar_y4",
                                    x, y,    dx, dy*4, -1,
                                    x, y+dy, dx, dy*2, +2 );
                                CV_WRITE_SEQ_ELEM( haarFeature, writer );
                            }
                        }
                    }

                    // x2_y2
                    if ( (x+dx*2 <= winsize.width) && (y+dy*2 <= winsize.height) ) {
                        if (dx*4*dy < s0) continue;
                        if (!symmetric || (x+x+dx*2 <=winsize.width)) {
                            haarFeature = cvHaarFeature( "haar_x2_y2",
                                x   , y,    dx*2, dy*2, -1,
                                x   , y   , dx  , dy,   +2,
                                x+dx, y+dy, dx  , dy,   +2 );
                            CV_WRITE_SEQ_ELEM( haarFeature, writer );
                        }
                    }

                    if (mode != 0 /*BASIC*/) {
                        // point
                        if ( (x+dx*3 <= winsize.width) && (y+dy*3 <= winsize.height) ) {
                            if (dx*9*dy < s0) continue;
                            if (!symmetric || (x+x+dx*3 <=winsize.width))  {
                                haarFeature = cvHaarFeature( "haar_point",//"haar_point"为3*3的小矩形
                                    x   , y,    dx*3, dy*3, -1,
                                    x+dx, y+dy, dx  , dy  , +9);
                                CV_WRITE_SEQ_ELEM( haarFeature, writer );
                            }
                        }
                    }

                    if (mode == 2 /*ALL*/) {
                        // tilted haar_x2                                      (x, y, w, h, b, weight)
                        if ( (x+2*dx <= winsize.width) && (y+2*dx+dy <= winsize.height) && (x-dy>= 0) ) {
                            if (dx*2*dy < s1) continue;

                            if (!symmetric || (x <= (winsize.width / 2) )) {
                                haarFeature = cvHaarFeature( "tilted_haar_x2",///??????????????????????????????
                                    x, y, dx*2, dy, -1,
                                    x, y, dx  , dy, +2 );
                                CV_WRITE_SEQ_ELEM( haarFeature, writer );
                            }
                        }

                        // tilted haar_y2                                      (x, y, w, h, b, weight)
                        if ( (x+dx <= winsize.width) && (y+dx+2*dy <= winsize.height) && (x-2*dy>= 0) ) {
                            if (dx*2*dy < s1) continue;

                            if (!symmetric || (x <= (winsize.width / 2) )) {
                                haarFeature = cvHaarFeature( "tilted_haar_y2",
                                    x, y, dx, 2*dy, -1,
                                    x, y, dx,   dy, +2 );
                                CV_WRITE_SEQ_ELEM( haarFeature, writer );
                            }
                        }

                        // tilted haar_x3                                   (x, y, w, h, b, weight)
                        if ( (x+3*dx <= winsize.width) && (y+3*dx+dy <= winsize.height) && (x-dy>= 0) ) {
                            if (dx*3*dy < s2) continue;

                            if (!symmetric || (x <= (winsize.width / 2) )) {
                                haarFeature = cvHaarFeature( "tilted_haar_x3",//?????????????????????????
                                    x,    y,    dx*3, dy, -1,
                                    x+dx, y+dx, dx  , dy, +3 );
                                CV_WRITE_SEQ_ELEM( haarFeature, writer );
                            }
                        }

                        // tilted haar_y3                                      (x, y, w, h, b, weight)
                        if ( (x+dx <= winsize.width) && (y+dx+3*dy <= winsize.height) && (x-3*dy>= 0) ) {
                            if (dx*3*dy < s2) continue;

                            if (!symmetric || (x <= (winsize.width / 2) )) {
                                haarFeature = cvHaarFeature( "tilted_haar_y3",//????????????????????????
                                    x,    y,    dx, 3*dy, -1,
                                    x-dy, y+dy, dx,   dy, +3 );
                                CV_WRITE_SEQ_ELEM( haarFeature, writer );
                            }
                        }


                        // tilted haar_x4                                   (x, y, w, h, b, weight)
                        if ( (x+4*dx <= winsize.width) && (y+4*dx+dy <= winsize.height) && (x-dy>= 0) ) {
                            if (dx*4*dy < s3) continue;

                            if (!symmetric || (x <= (winsize.width / 2) )) {
                                haarFeature = cvHaarFeature( "tilted_haar_x4",//??????????????????????


                                    x,    y,    dx*4, dy, -1,
                                    x+dx, y+dx, dx*2, dy, +2 );
                                CV_WRITE_SEQ_ELEM( haarFeature, writer );
                            }
                        }

                        // tilted haar_y4                                      (x, y, w, h, b, weight)
                        if ( (x+dx <= winsize.width) && (y+dx+4*dy <= winsize.height) && (x-4*dy>= 0) ) {
                            if (dx*4*dy < s3) continue;

                            if (!symmetric || (x <= (winsize.width / 2) )) {
                                haarFeature = cvHaarFeature( "tilted_haar_y4",//????????????????
                                    x,    y,    dx, 4*dy, -1,
                                    x-dy, y+dy, dx, 2*dy, +2 );
                                CV_WRITE_SEQ_ELEM( haarFeature, writer );
                            }
                        }


                        /*

                          // tilted point
                          if ( (x+dx*3 <= winsize.width - 1) && (y+dy*3 <= winsize.height - 1) && (x-3*dy>= 0)) {
                          if (dx*9*dy < 36) continue;
                          if (!symmetric || (x <= (winsize.width / 2) ))  {
                            haarFeature = cvHaarFeature( "tilted_haar_point",
                                x, y,    dx*3, dy*3, -1,
                                x, y+dy, dx  , dy,   +9 );
                                CV_WRITE_SEQ_ELEM( haarFeature, writer );
                          }
                          }
                        */
                    }
                }
            }
        }
    }

    seq = cvEndWriteSeq( &writer );//函数cvEndWriteSeq完成写入操作并返回指向被写入元素的序列的地址,
	                               //同时,函数将截取最后那个不完整的序列块.块的剩余部分返回到内存之后,序列即可以被安全地读和写.
    features = (CvIntHaarFeatures*) cvAlloc( sizeof( CvIntHaarFeatures ) +
        ( sizeof( CvTHaarFeature ) + sizeof( CvFastHaarFeature ) ) * seq->total );
	//opencv中所有的内存分配和释放都是通过cvAlloc和cvFree合作完成的.
	//如果cvAlloc/cvFree不是匹配出现, 那么可以认为出现了内存泄漏.
    features->feature = (CvTHaarFeature*) (features + 1);
    features->fastfeature = (CvFastHaarFeature*) ( features->feature + seq->total );
    features->count = seq->total;
    features->winsize = winsize;
	//复制序列的全部或部分到一个连续内存数组中;
    cvCvtSeqToArray( seq, (CvArr*) features->feature );
    cvReleaseMemStorage( &storage );
	//将普通的特征转化为快速计算的haar特征
    icvConvertToFastHaarFeature( features->feature, features->fastfeature,
                                 features->count, (winsize.width + 1) );

    return features;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值