icvCreateIntHaarFeatures超详细解析(不看你会后悔的)
来源:互联网 发布:淘宝拍a发b处罚 编辑:程序博客网 时间:2024/04/28 13:01
本博是笔者读书笔记整理,欢迎转载,请注明出处,如有不足,还望网友们指教。
/* * icvCreateIntHaarFeatures * * Create internal representation of haar features * * mode: * 0 - BASIC = Viola * 1 - CORE = All upright * 2 - ALL = All features *///功能:针对大小为winsize的图像,计算所有的HaarFeature的rect,并存入features 返回输入staticCvIntHaarFeatures* 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;}
0 0
- icvCreateIntHaarFeatures超详细解析(不看你会后悔的)
- 经典异常 不看你会后悔的
- 世上超损人的100句话,不看会后悔,你可以从中学习两句
- 不看会后悔的
- 经典语录!不看你会后悔!
- 致逝去的NOKIA,不看你会后悔哦
- 杀人后一个孩子的做法…不看你会后悔的…(转)
- 观手知健康(不看你真的会后悔)别错过
- 结婚的那天晚上,不看你会后悔的!~!~12月3日 14:48
- 【转】杀人后一个孩子的做法…不看你会后悔的…
- 杀人后一个孩子的做法…不看你会后悔的…
- [推荐]助你流量稳涨的淘宝知识,不看会后悔的!
- 考考你智力:十大欺骗眼睛的图片!!不看会后悔哦!!^O^
- 2-SAT暴力dfs模板解释|不看你会后悔的
- 分享在github超酷超炫特效动画,不看你会后悔的。
- [干货]总结的真好,Android重点知识点总结,不看你会后悔!
- 干货来了,19个完整app正在赶来,不看你会后悔的
- 我是有原则的 !~~~~~~~ 不看你后悔!~~~~
- 【0-1】矩阵分解
- Mysql数据库中文乱码问题之解决方法
- [太炫酷了]让你的CheckBox嗨起来
- android 读取本地或网络图片,转换为Bitmap 并保存本地中
- unity3d shader 学习笔记
- icvCreateIntHaarFeatures超详细解析(不看你会后悔的)
- NYOJ 103 A+B Problem II
- 9.4 GestureRecognizer muli 多个
- oracle 查看用户所在的表空间
- 开发日记(4)Android的图片压缩类ThumbnailUtils
- 自定义Dialog
- iOS之 KVO实例代码应用
- grep用法详解 grep与正则表达式
- 如何打一手好Log