opencv源码解读读书笔记:负样本的有关源代码
2015-06-03 16:18
567 查看
本文为笔者读书笔记,欢迎转载,请注明本博,谢谢。如有不足,请大家多多指教。
![](http://static.blog.csdn.net/xheditor/xheditor_emot/default/laugh.gif)
1 CvBackgrounData和CvBackgroundReader
2 icvGetBackgroundImage
3 icvGetNextFromBackgroundData
有些代码我还没有看懂,不敢乱注释,以免误导大家,请友友们见谅哈
也有人说这是个抠图的过程,比如http://blog.csdn.net/longzaitianya1989/article/details/8174768
具体抠图过程为:
1) 确定抠图区域的左上角坐标(Point.x, Point.y)
2) 确定一个最小缩放比例,使得原负样本图像缩放后恰好包含选中负样本区域
3) 对原负样本图象按计算好的缩放比例进行缩放
4) 在缩放后的图像上抠出负样本
如图:
![](http://img.blog.csdn.net/20150603220746737?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZGluZzk3NzkyMTgzMA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
本图选自http://blog.csdn.net/lampqiu/article/details/40188763
参考内容:
1 《学习opencv》于仕琪
2 http://blog.csdn.net/lampqiu/article/details/40188763
![](http://static.blog.csdn.net/xheditor/xheditor_emot/default/laugh.gif)
1 CvBackgrounData和CvBackgroundReader
/* *存放负样本文件的结构体 */ typedef struct CvBackgroundData { int count; //负样本的数量 char** filename; //负样本的文件名包括绝对路径和扩展名 int last; int round; CvSize winsize; //大小 } CvBackgroundData; /* *在训练过程中,由于负样本的大小不一定是等于正样本的(必须是大于等于正样本), *所以在训练过程中,需要抠出与正样本一样大的ROI区域,就是该结构体表示roi区域 */ typedef struct CvBackgroundReader{ CvMat src; //未处理的负样本原图像 CvMat img; //扣取的负样本 CvPoint offset; //扣取负样本的左上角的坐标 float scale; //代表了缩放的比例 float scalefactor; //不知道为什么两个缩放因子 float stepfactor; CvPoint point; } CvBackgroundReader
2 icvGetBackgroundImage
/* *icvGetBackgroundImage获取负样本,训练的负样本可以比正样本大 *但是该函数索取的负样本是在负样本中取得跟正样本一样大的区域 */ static void icvGetBackgroundImage( CvBackgroundData* data, //如上所示 CvBackgroundReader* reader, CvMat* img ) { CvMat mat; assert( data != NULL && reader != NULL && img != NULL ); assert( CV_MAT_TYPE( img->type ) == CV_8UC1 ); assert( img->cols == data->winsize.width ); assert( img->rows == data->winsize.height ); /*在if中的reader->img.data.ptr 这个data与CvBackgroundData* data中的data是不一样的 *reader->img.data.ptr:这个data是个union(共同体),data中的ptr存储的是data数据的第一个元素。 *CvBackgroundData* data:如上所示 */ if( reader->img.data.ptr == NULL ) //含义是如果reader读入的图片的数据为空 { icvGetNextFromBackgroundData( data, reader ); } mat = cvMat( data->winsize.height, data->winsize.width, CV_8UC1 ); cvSetData(&mat, (void*) (reader->img.data.ptr + reader->point.y * reader->img.step + reader->point.x * sizeof( uchar )), reader->img.step ); cvCopy( &mat, img, 0 ); //若负样本图像很大,我们可以在一幅图中不断调整切割的位置 //直至遍历完整个图像 //沿x方向移动 if( (int) ( reader->point.x + (1.0F + reader->stepfactor ) * data->winsize.width ) < reader->img.cols ) { reader->point.x += (int) (reader->stepfactor * data->winsize.width); } else { //置为x.offset(相当于x方向移动不下去了,按y方向移动) reader->point.x = reader->offset.x; //延y方向移动 if( (int) ( reader->point.y + (1.0F + reader->stepfactor ) * data->winsize.height ) < reader->img.rows ) { reader->point.y += (int) (reader->stepfactor * data->winsize.height); } else { reader->point.y = reader->offset.y; reader->scale *= reader->scalefactor; if( reader->scale <= 1.0F ) { reader->img = cvMat( (int) (reader->scale * reader->src.rows), (int) (reader->scale * reader->src.cols), CV_8UC1, (void*) (reader->img.data.ptr) ); cvResize( &(reader->src), &(reader->img) ); } else { icvGetNextFromBackgroundData( data, reader ); } } } }
3 icvGetNextFromBackgroundData
有些代码我还没有看懂,不敢乱注释,以免误导大家,请友友们见谅哈
/* *icvGetNextFromBackgroundData *功能:将负样本的属性信息存放在reader中,属性信息有负样本的长,宽,数量等 */ static void icvGetNextFromBackgroundData( CvBackgroundData* data, CvBackgroundReader* reader ) { IplImage* img = NULL; char* filename = NULL; size_t datasize = 0; int round = 0; int i = 0; CvPoint offset = cvPoint(0,0); assert( data != NULL && reader != NULL ); if( reader->src.data.ptr != NULL ) { cvFree( &(reader->src.data.ptr) ); reader->src.data.ptr = NULL; } if( reader->img.data.ptr != NULL ) { cvFree( &(reader->img.data.ptr) ); reader->img.data.ptr = NULL; } #ifdef _OPENMP #pragma omp critical(c_background_data) #endif /* _OPENMP */ { for( i = 0; i < data->count; i++ ) { round = data->round; //#ifdef CV_VERBOSE // printf( "Open background image: %s\n", data->filename[data->last] ); //#endif /* CV_VERBOSE */ img = cvLoadImage( data->filename[data->last++], 0 ); if( !img ) continue; data->round += data->last / data->count; data->round = data->round % (data->winsize.width * data->winsize.height); data->last %= data->count; offset.x = round % data->winsize.width; offset.y = round / data->winsize.width; offset.x = MIN( offset.x, img->width - data->winsize.width ); offset.y = MIN( offset.y, img->height - data->winsize.height ); if( img != NULL && img->depth == IPL_DEPTH_8U && img->nChannels == 1 && offset.x >= 0 && offset.y >= 0 ) { break; } if( img != NULL ) cvReleaseImage( &img ); img = NULL; } } if( img == NULL ) { /* no appropriate image */ #ifdef CV_VERBOSE printf( "Invalid background description file.\n" ); #endif /* CV_VERBOSE */ assert( 0 ); exit( 1 ); } datasize = sizeof( uchar ) * img->width * img->height; reader->src = cvMat( img->height, img->width, CV_8UC1, (void*) cvAlloc( datasize ) ); cvCopy( img, &reader->src, NULL ); cvReleaseImage( &img ); img = NULL; //reader->offset.x = round % data->winsize.width; //reader->offset.y = round / data->winsize.width; reader->offset = offset; reader->point = reader->offset; reader->scale = MAX( ((float) data->winsize.width + reader->point.x) / ((float) reader->src.cols), ((float) data->winsize.height + reader->point.y) / ((float) reader->src.rows) ); //将负样本大小放缩到包含正样本大小的最小尺寸 reader->img = cvMat( (int) (reader->scale * reader->src.rows + 0.5F), (int) (reader->scale * reader->src.cols + 0.5F), CV_8UC1, (void*) cvAlloc( datasize ) ); cvResize( &(reader->src), &(reader->img) ); }
也有人说这是个抠图的过程,比如http://blog.csdn.net/longzaitianya1989/article/details/8174768
具体抠图过程为:
1) 确定抠图区域的左上角坐标(Point.x, Point.y)
2) 确定一个最小缩放比例,使得原负样本图像缩放后恰好包含选中负样本区域
3) 对原负样本图象按计算好的缩放比例进行缩放
4) 在缩放后的图像上抠出负样本
如图:
本图选自http://blog.csdn.net/lampqiu/article/details/40188763
参考内容:
1 《学习opencv》于仕琪
2 http://blog.csdn.net/lampqiu/article/details/40188763
相关文章推荐
- C语言 全排列
- 水印php
- 《Java编程思想》学习笔记10——文件和目录常用操作
- Java RMI之HelloWorld篇
- 多个返回 顶部的代码
- Matlab符号微积分练习
- Java学习 - Thread的Stop方法以及替换实现
- 关于GoogleMap的使用经验
- 《Java编程思想》学习笔记8——泛型编程高级
- yii 下拉框
- Openstack: python API “how to download image from glance using the python api”
- 《Java编程思想》学习笔记9——集合容器高级
- php_mysql注入load_file()IIS配置文件获取
- 《Java编程思想》学习笔记6——Java动态代理
- 《Java编程思想》学习笔记7——泛型编程基础
- eclipse git提交代码
- 8位灰度图二维卷积高斯模糊(VC++)
- java.lang.OutOfMemoryError: Java heap space
- java基础(八)---map
- Python中__getitem__()和__setitem__()的使用实例