vec

在我们开始训练我们的Haar分类器之前,首先要对样本进行处理。

人脸识别的尝试系列(一)中:http://blog.csdn.net/u011583927/article/details/44627493

我们已经提到了如何准备我们的样本,在如下图准备好样本之后

vec_第1张图片

需要在cmd窗口中调用类似如下的命令生成vec文件

opencv_createsamples.exe–vec pos.vec –info pos_image.txt –bg neg_image.txt –w 24 –h 24 –num 400

那么具体是如何生成的vec文件的,下面是具体的实现代码以及根据我个人理解加上的详细注释

为方便大家理解,代码中插入了两张图片,分别展示了相应区域代码的执行结果


[cpp] view plain copy print ?
  1. /* 
  2.  * createsamples.cpp 生成vec文件的可执行程序的具体实现 
  3.  * 
  4.  * Create test/training samples        利用描述正样本和负样本的txt文件创建vec文件 
  5.  * 命令行示例: 
  6. opencv_createsamples.exe –vec pos.vec –info pos_image.txt –bg neg_image.txt –w 24 –h 24 –num 400 
  7. *需要先将命令行的地址调到当前文件夹下 
  8.  */  
  9.   
  10. #include   
  11. #include   
  12. #include   
  13. #include   
  14. #include   
  15. #include   
  16.   
  17. using namespace std;  
  18.   
  19. #include "cvhaartraining.h"  
  20. #include "ioutput.h"  
  21.   
  22.   
  23. int main( int argc, char* argv[] )  
  24. {  
  25.     //参数初始化  
  26.     int i = 0;  
  27.     char* nullname   = (char*)"(NULL)";  
  28.     char* vecname    = NULL; /* .vec file name */  
  29.     char* infoname   = NULL; //file name with marked up image descriptions正样本描述文件路径  
  30.     char* imagename  = NULL; /* single sample image  单个正样本图片*/  
  31.     char* bgfilename = NULL; /* background  负样本描述文件路径 */  
  32.     int num = 1000;  
  33.     int bgcolor = 0;  
  34.     int bgthreshold = 80;  
  35.     int invert = 0;  
  36.     int maxintensitydev = 40;// max_intensity_deviation  
  37.     double maxxangle = 1.1;  
  38.     double maxyangle = 1.1;  
  39.     double maxzangle = 0.5;  
  40.     bool showsamples = false;  
  41.     /* the samples are adjusted to this scale in the sample preview window */  
  42.     double scale = 4.0;  
  43.     int width  = 24;  
  44.     int height = 24;  
  45.     bool pngoutput = false/* whether to make the samples in png or in jpg*/  
  46.   
  47.     srand((unsigned int)time(0));  
  48.       
  49.     //如果只输入opencv_createsamples.exe 相当于查看命令行参数使用  
  50.     if( argc == 1 )  
  51.     {  
  52.         printf( "Usage: %s\n  [-info ]\n"  
  53.                 "  [-img ]\n"  
  54.                 "  [-vec ]\n"  
  55.                 "  [-bg ]\n  [-num ]\n"  
  56.                 "  [-bgcolor ]\n"  
  57.                 "  [-inv] [-randinv] [-bgthresh ]\n"  
  58.                 "  [-maxidev ]\n"  
  59.                 "  [-maxxangle ]\n"  
  60.                 "  [-maxyangle ]\n"  
  61.                 "  [-maxzangle ]\n"  
  62.                 "  [-show []]\n"  
  63.                 "  [-w ]\n  [-h ]\n"  
  64.                 "  [-pngoutput]",  
  65.                 argv[0], num, bgcolor, bgthreshold, maxintensitydev,  
  66.                 maxxangle, maxyangle, maxzangle, scale, width, height );  
  67.   
  68.         return 0;  
  69.     }  
vec_第2张图片
[cpp] view plain copy print ?
  1.  for( i = 1; i < argc; ++i )  
  2. {  
  3.         //strcmp(str1,str2)函数:比较两个字符串。  
  4. //相等返回0;str1>str2返回正数;str1  
  5.         if( !strcmp( argv[i], "-info" ) )  
  6.         {  
  7.             //argv[i]==”-info”  
  8.             infoname = argv[++i];  
  9.         }  
  10.         else if( !strcmp( argv[i], "-img" ) )  
  11.         {  
  12.             imagename = argv[++i];  
  13.         }  
  14.         else if( !strcmp( argv[i], "-vec" ) )  
  15.         {  
  16.             vecname = argv[++i];  
  17.         }  
  18.         else if( !strcmp( argv[i], "-bg" ) )  
  19.         {  
  20.             bgfilename = argv[++i];  
  21.         }  
  22.         else if( !strcmp( argv[i], "-num" ) )  
  23.         {  
  24.             //atoi 把一个字符串转化成整形  
  25.             num = atoi( argv[++i] );  
  26.         }  
  27.         else if( !strcmp( argv[i], "-bgcolor" ) )  
  28.         {  
  29.             bgcolor = atoi( argv[++i] );  
  30.         }  
  31.         else if( !strcmp( argv[i], "-bgthresh" ) )  
  32.         {  
  33.             bgthreshold = atoi( argv[++i] );  
  34.         }  
  35.         else if( !strcmp( argv[i], "-inv" ) )  
  36.         {  
  37.            //输入含-inv指令  
  38.             invert = 1;  
  39.         }  
  40.         else if( !strcmp( argv[i], "-randinv" ) )  
  41.         {  
  42.            //输入含-randinv指令  
  43.             invert = CV_RANDOM_INVERT;  
  44.         }  
  45.         else if( !strcmp( argv[i], "-maxidev" ) )  
  46.         {  
  47.             maxintensitydev = atoi( argv[++i] );  
  48.         }  
  49.         else if( !strcmp( argv[i], "-maxxangle" ) )  
  50.         {  
  51.             maxxangle = atof( argv[++i] );  
  52.         }  
  53.         else if( !strcmp( argv[i], "-maxyangle" ) )  
  54.         {  
  55.             maxyangle = atof( argv[++i] );  
  56.         }  
  57.         else if( !strcmp( argv[i], "-maxzangle" ) )  
  58.         {  
  59.             maxzangle = atof( argv[++i] );  
  60.         }  
  61.         else if( !strcmp( argv[i], "-show" ) )  
  62.         {  
  63.             showsamples = true;  
  64.             if( i+1 < argc && strlen( argv[i+1] ) > 0 && argv[i+1][0] != '-' )  
  65.             {  
  66.                 double d;  
  67.                 d = strtod( argv[i+1], 0 );  
  68.                 if( d != -HUGE_VAL && d != HUGE_VAL && d > 0 ) scale = d;  
  69.                 ++i;  
  70.             }  
  71.         }  
  72.         else if( !strcmp( argv[i], "-w" ) )  
  73.         {  
  74.             width = atoi( argv[++i] );  
  75.         }  
  76.         else if( !strcmp( argv[i], "-h" ) )  
  77.         {  
  78.             height = atoi( argv[++i] );  
  79.         }  
  80.         else if( !strcmp( argv[i], "-pngoutput" ) )  
  81.         {  
  82.             pngoutput = true;  
  83.         }  
  84.     }  
  85.   
  86.     printf( "Info file name: %s\n", ((infoname == NULL) ?   nullname : infoname ) );  
  87.     printf( "Img file name: %s\n",  ((imagename == NULL) ?  nullname : imagename ) );  
  88.     printf( "Vec file name: %s\n",  ((vecname == NULL) ?    nullname : vecname ) );  
  89.     printf( "BG  file name: %s\n",  ((bgfilename == NULL) ? nullname : bgfilename ) );  
  90.     printf( "Num: %d\n", num );  
  91.     printf( "BG color: %d\n", bgcolor );  
  92.     printf( "BG threshold: %d\n", bgthreshold );  
  93.     printf( "Invert: %s\n", (invert == CV_RANDOM_INVERT) ? "RANDOM"  
  94.                                 : ( (invert) ? "TRUE" : "FALSE" ) );  
  95.     printf( "Max intensity deviation: %d\n", maxintensitydev );  
  96.     printf( "Max x angle: %g\n", maxxangle );  
  97.     printf( "Max y angle: %g\n", maxyangle );  
  98.     printf( "Max z angle: %g\n", maxzangle );  
  99.     printf( "Show samples: %s\n", (showsamples) ? "TRUE" : "FALSE" );  
  100.     if( showsamples )  
  101.     {  
  102.         printf( "Scale applied to display : %g\n", scale );  
  103.     }  
  104.     if( !pngoutput)  
  105.     {  
  106.         printf( "Original image will be scaled to:\n");  
  107.         printf( "\tWidth: $backgroundWidth / %d\n", width );  
  108.         printf( "\tHeight: $backgroundHeight / %d\n", height );  
  109.     }  
  110.   
  111.     /* determine action  (通过关键命令)确定行为*/  
  112.     if( imagename && vecname )  
  113.     {  
  114.         printf( "Create training samples from single image applying distortions...\n" );  
  115.   
  116.         cvCreateTrainingSamples( vecname, imagename, bgcolor, bgthreshold, bgfilename,  
  117.                                  num, invert, maxintensitydev,  
  118.                                  maxxangle, maxyangle, maxzangle,  
  119.                                  showsamples, width, height );  
  120.   
  121.         printf( "Done\n" );  
  122.     }  
  123.     else if( imagename && bgfilename && infoname)  
  124.     {  
  125.         printf( "Create data set from single image applying distortions...\n"  
  126.                 "Output format: %s\n",  
  127.                 (( pngoutput ) ? "PNG" : "JPG") );  
  128.   
  129.         std::auto_ptr creator;  
  130.         if( pngoutput )  
  131.         {  
  132.             creator = std::auto_ptrnew PngDatasetGenerator( infoname ) );  
  133.         }  
  134.         else  
  135.         {  
  136.             creator = std::auto_ptrnew JpgDatasetGenerator( infoname ) );  
  137.         }  
  138.         creator->create( imagename, bgcolor, bgthreshold, bgfilename, num,  
  139.                         invert, maxintensitydev, maxxangle, maxyangle, maxzangle,  
  140.                         showsamples, width, height );  
  141.   
  142.         printf( "Done\n" );  
  143.     }  
  144.     else if( infoname && vecname )  
  145. {  
  146.         //生成vec文件,我们使用的这种命令  
  147.         //命令包括正样本描述文件的文件名,准备生成的vec文件的文件名  
  148.         int total;  
  149.         printf( "Create training samples from images collection...\n" );  
  150.         total = cvCreateTrainingSamplesFromInfo( infoname, vecname, num, showsamples,  
  151.                                                  width, height );  
  152.         printf( "Done. Created %d samples\n", total );  
  153.     }  
  154.     else if( vecname )  
  155. {  
  156.         //查看vec文件  
  157.         //命令不包含正样本文件,背景样本文件,单个正样本图像,只包含vec文件路径  
vec_第3张图片
[cpp] view plain copy print ?
  1.  printf( "View samples from vec file (press ESC to exit)...\n" );  
  2.   
  3.         cvShowVecSamples( vecname, width, height, scale );  
  4.   
  5.         printf( "Done\n" );  
  6.     }  
  7.     else  
  8.     {  
  9.         printf( "Nothing to do\n" );  
  10.     }  
  11.   
  12.     return 0;  
  13. }  
  14.   
  15.   
  16. cvCreateTrainingSamplesFromInfo函数的具体实现  
  17. 为方便理解,对应于上面我们输入的命令来进行解释  
  18. -infoname    pos_image.txt 正样本描述文件文件名  
  19. -vecfilename pos.vec 这个参数相当于指定创建的vec文件的名字,函数执行前这个vec文件并不存在  
  20. -num         400 正样本总数   
  21. -showsamples false 是否显示样本  
  22. -width  
  23. -height  
  24. int cvCreateTrainingSamplesFromInfo( const char* infoname, const char* vecfilename,  
  25.                                      int num,  
  26.                                      int showsamples,  
  27.                                      int winwidth, int winheight )  
  28. {  
  29.     char fullname[PATH_MAX];  
  30.     char* filename;  
  31.   
  32.     FILE* info;  
  33.     FILE* vec;  
  34.     IplImage* src=0;  
  35.     IplImage* sample;  
  36.     int line;  
  37.     int error;  
  38.     int i;  
  39.     int x, y, width, height;  
  40.     int total;  
  41.       
  42.     /* 
  43. #include  
  44. void assert( int expression ); 
  45. assert的作用是现计算表达式 expression ,如果其值为假(即为0),那么它先向stderr打印一条出错信息,然后通过调用 abort 来终止程序运行。*/  
  46.   
  47.     assert( infoname != NULL );  
  48.     assert( vecfilename != NULL );  
  49.   
  50.     total = 0;  
  51.     if( !icvMkDir( vecfilename ) )  
  52. {  
  53.         // icvMkDir()   
  54. //个人理解:判断文件名vecfilename是否只包含文件名,不包含路径  
  55.         //例如:pos.veg返回1  D:\\pos.veg返回0  
  56.         //若只包含文件名,返回1,否则返回0  
  57.   
  58. #if CV_VERBOSE  
  59.         fprintf( stderr, "Unable to create directory hierarchy: %s\n", vecfilename );  
  60. #endif /* CV_VERBOSE */  
  61.   
  62.         return total;  
  63.     }  
  64.   
  65.     info = fopen( infoname, "r" );//以只读方式打开文件infoname,若文件不存在不创建该文件(即返回null)  
  66.     if( info == NULL )  
  67.     {  
  68.   
  69. #if CV_VERBOSE  
  70.         fprintf( stderr, "Unable to open file: %s\n", infoname );  
  71. #endif /* CV_VERBOSE */  
  72.   
  73.         return total;  
  74.     }  
  75.   
  76.     vec = fopen( vecfilename, "wb" );// 以二进制写方式打开文件,若文件不存在则创建该文件  
  77.     if( vec == NULL )  
  78.     {  
  79.   
  80. #if CV_VERBOSE  
  81.         fprintf( stderr, "Unable to open file: %s\n", vecfilename );  
  82. #endif /* CV_VERBOSE */  
  83.   
  84.         fclose( info );  
  85.   
  86.         return total;  
  87.     }  
  88.       
  89.     //创建一个单通道byte图像  
  90.     sample = cvCreateImage( cvSize( winwidth, winheight ), IPL_DEPTH_8U, 1 );  
  91.   
  92.     //写vec文件头  
  93.     icvWriteVecHeader( vec, num, sample->width, sample->height );  
  94.   
  95.     if( showsamples )  
  96.     {  
  97.         cvNamedWindow( "Sample", CV_WINDOW_AUTOSIZE );  
  98.     }  
  99.   
  100. strcpy( fullname, infoname );  
  101.   
  102. /*strrchr() 函数查找字符在指定字符串中从后面开始的第一次出现的位置,如果成功,则返回从该位置到字符串结尾的所有字符,如果失败,则返回 false。与之相对应的是strchr()函数,它查找字符串中首次出现指定字符的位置。*/  
  103.     filename = strrchr( fullname, '\\' );//获取正样本描述文件的文件名,剔除路径  
  104.     if( filename == NULL )  
  105.     {  
  106.         filename = strrchr( fullname, '/' );  
  107.     }  
  108.     if( filename == NULL )  
  109.     {  
  110.         filename = fullname;  
  111.     }  
  112.     else  
  113. {  
  114.         //正常情况,将指针指向‘\’后面的第一个字符  
  115.         filename++;  
  116.     }  
  117.       
  118.     //遍历每张正样本图片,将其信息写入vec文件  
  119.     for( line = 1, error = 0, total = 0; total < num ;line++ )  
  120.     {  
  121.         int count;  
  122.           
  123. /*  
  124. fscanf功能: 从一个流中执行格式化输入,fscanf遇到空格和换行时结束,注意空格时也结束。 
  125. intfscanf(FILE*stream,constchar*format,[argument...]); 
  126. FILE *stream:文件指针; 
  127. char *format:格式字符串; 
  128. [argument...]:输入列表。 
  129. 返回值:整型,成功读入的参数的个数 
  130. */  
  131.         error = ( fscanf( info, "%s %d", filename, &count ) != 2 );   
  132. //info——正样本描述文件的文件流     
  133. // 正样本描述文件每一行的格式  pos_image/0.bmp 1 0 0 24 24  
  134. //注意!filename是指向fullname的指针。所以这里以filename作为读入数据的参数,实际上修改的是fullname的内容。读入信息后fullname表示某一个正样本图片的地址(相对路径)  
  135. //count 表示文件的个数  
  136.           
  137. if( !error )//说明读取是正确的,获取样本图片  
  138.         {  
  139.             src = cvLoadImage( fullname, 0 );//读取一副正样本图像(强制转化为灰度图像)  
  140.             error = ( src == NULL );  
  141.             if( error )  
  142.             {  
  143.   
  144. #if CV_VERBOSE  
  145.                 fprintf( stderr, "Unable to open image: %s\n", fullname );  
  146. #endif /* CV_VERBOSE */  
  147.   
  148.             }  
  149.         }  
  150.   
  151.         //遍历当前样本图片中的所有子窗口样本。  
  152.         //一般情况下的使用方法是只有一个子窗口也就是整幅样本图片,  
  153. 即count=1,且x=0 y=0 width height就是样本的宽和高   
  154.         for( i = 0; (i < count) && (total < num); i++, total++ )  
  155.         {  
  156.             error = ( fscanf( info, "%d %d %d %d", &x, &y, &width, &height ) != 4 );  
  157.            //读取当前图像的顶点坐标以及长宽  
  158.             if( error ) break;  
  159.            // cvSetImageROI 基于给定的矩形设置图像的ROI(感兴趣区域)  
  160.             cvSetImageROI( src, cvRect( x, y, width, height ) );  
  161.              
  162. void cvResize( const CvArr* src, CvArr* dst, int interpolation=CV_INTER_LINEAR );  
  163.            函数cvResize()功能: 重新调整图像src(或它的ROI),使它精确匹配目标dst(或其ROI)。这里需要说明的是,cvResize可以用来调整3通道图像(如RGB图像)和单通道图像的大小。  
  164.            src 源图像;  dst 目标图像  
  165.             cvResize( src, sample, width >= sample->width &&  
  166.                       height >= sample->height ? CV_INTER_AREA : CV_INTER_LINEAR );  
  167.   
  168.             if( showsamples )  
  169.             {  
  170.                 cvShowImage( "Sample", sample );  
  171.                 if( cvWaitKey( 0 ) == 27 )  
  172.                 {  
  173.                     showsamples = 0;  
  174.                 }  
  175.             }  
  176.            //将当前这幅样本图片信息写入vec文件中  
  177.             icvWriteVecSample( vec, sample );  
  178.         }  
  179.           
  180.         //释放当前的图片占用的内存  
  181.         if( src )  
  182.         {  
  183.             cvReleaseImage( &src );  
  184.         }  
  185.   
  186.         if( error )  
  187.         {  
  188.   
  189. #if CV_VERBOSE  
  190.             fprintf( stderr, "%s(%d) : parse error", infoname, line );  
  191. #endif /* CV_VERBOSE */  
  192.   
  193.             break;  
  194.         }  
  195.     }  
  196.   
  197.     if( sample )  
  198.     {  
  199.         cvReleaseImage( &sample );  
  200.     }  
  201.   
  202.     fclose( vec );  
  203.     fclose( info );  
  204.   
  205.     return total;  
  206. }  




0
0
 
 

我的同类文章

数字图像处理与计算机视觉(16)
  • VS2015上配置opencv2.4.112016-09-04阅读228
  • 将图像绘制成3维立体散点图2016-01-01阅读114
  • Distinctive Image Features from Scale-Invariant Keypoints-SIFT算法译文2015-12-05阅读194
  • 快速傅里叶变换(FFT)2015-07-21阅读876
  • 计算机视觉领域的一些牛人博客,超有实力的研究机构等的网站链接2015-05-02阅读403
  • opencv视频读写和视频等间隔采样2015-04-14阅读412
  • C#灰度图转伪彩色图2016-01-17阅读238
  • 浅入浅出理解傅里叶变换2015-12-29阅读248
  • 快速傅里叶变换(FFT)的C#实现及详细注释2015-07-21阅读1754
  • 如何理解离散傅里叶变换(一)实数形式傅里叶变换2015-05-23阅读651
  • opencv感兴趣通道COI的使用2015-04-21阅读262
更多文章
猜你在找
windows命令行教程 数据结构和算法 数据结构基础系列(1):数据结构和算法 C语言系列之 递归算法示例与 Windows 趣味小项目 以性别预测为例,谈谈数据挖掘中常见的分类算法
DeepLearning tutorial5CNN卷积神经网络应用于人脸识别详细流程+代码实现 CNN卷积神经网络应用于人脸识别详细流程+代码实现 CNN卷积神经网络应用于人脸识别详细流程+代码实现 Android实现人脸识别的详细过程 在Android实现人脸识别的详细过程
查看评论

  暂无评论

* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
核心技术类目
全部主题 Hadoop AWS 移动游戏 Java Android iOS Swift 智能硬件 Docker OpenStack VPN Spark ERP IE10 Eclipse CRM JavaScript 数据库 Ubuntu NFC WAP jQuery BI HTML5 Spring Apache .NET API HTML SDK IIS Fedora XML LBS Unity Splashtop UML components Windows Mobile Rails QEMU KDE Cassandra CloudStack FTC coremail OPhone CouchBase 云计算 iOS6 Rackspace Web App SpringSide Maemo Compuware 大数据 aptech Perl Tornado Ruby Hibernate ThinkPHP HBase Pure Solr Angular Cloud Foundry Redis Scala Django Bootstrap
个人资料
vec_第4张图片
u011583927
3
  • 访问:17523次
  • 积分:586
  • 等级:
  • 排名:千里之外
  • 原创:38篇
  • 转载:7篇
  • 译文:0篇
  • 评论:9条
文章分类
  • 数字图像处理与计算机视觉(17)
  • Machine Learning(7)
  • Deep Learning(1)
  • C++(2)
  • C#(9)
  • 网络通信与多线程(2)
  • 不稳定的传送门(1)
  • 最优化算法(5)
  • 风机桨叶识别与故障诊断项目(7)
阅读排行
  • 快速傅里叶变换(FFT)的C#实现及详细注释(1751)
  • 机器学习(Machine Learning)&深度学习(Deep Learning)资料(1114)
  • K 近邻算法(KNN)与KD 树实现(981)
  • createsamples.cpp中生成vec文件的实现及详细注释、图解——人脸识别的尝试系列(三)(887)
  • 快速傅里叶变换(FFT)(875)
  • 如何理解离散傅里叶变换(一)实数形式傅里叶变换(645)
  • 最优化学习笔记(三)最速下降法(643)
  • 利用OpenCV的Haar特征目标检测方法进行人脸识别的尝试(一)(634)
  • Socket通用TCP通信协议设计及实现(防止粘包,可移植,可靠)(608)
  • C#复数类Complex的封装(605)
最新评论
  • C#复数类Complex的封装

    a15264311769:你好,请问您说的ToString()的重载方法有一些小问题,不知道怎么改!您能说下吗?

  • 快速傅里叶变换(FFT)的C#实现及详细注释

    u011583927:@a15264311769:您好,上面的算法是可以直接用的,但要注意我这里的是基2的快速傅里叶变换,...

  • 快速傅里叶变换(FFT)的C#实现及详细注释

    a15264311769:你好,上面的FFT,可不可以直接调用!

  • 风机桨叶故障诊断(三) 识别桨叶——初步构建BP神经网络

    lwqaitd:学到了,博主加油!!!

  • 风机桨叶故障诊断(七) 滑动窗与非极大值抑制NMS

    u011583927:对csdn的这个博客的编辑功能也真是无奈,认真写了许久发出来排版成了这样

  • 快速傅里叶变换(FFT)的C#实现及详细注释

    u011583927:不知为什么发表出来后格式出了问题。有一小部分文字看不到了,其中比较重要的是我提供了一个封装好的复数类...

  • C#复数类Complex的封装

    u011583927:补充一下,今天发现,ToString()的重载方法有一些小问题,大家仔细看一下如果使用改过来就好。

  • Socket通用TCP通信协议设计及实现(防止粘包,可移植,可靠)

    u011583927:@pandaCat123:当然可以,私信或者QQ都可以,这是我的QQ276527115。Socket...

  • Socket通用TCP通信协议设计及实现(防止粘包,可移植,可靠)

    pandaCat123:你好,我想私下请教你下一些socket通讯相关的问题,你在吗能否回我私信?

你可能感兴趣的:(vec)