vec

来源:互联网 发布:淘宝如何清空收藏夹 编辑:程序博客网 时间:2024/05/21 17:05

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

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

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


需要在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 <cstdio>  
  11. #include <cstring>  
  12. #include <cstdlib>  
  13. #include <cmath>  
  14. #include <ctime>  
  15. #include <memory>  
  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 <collection_file_name>]\n"  
  53.                 "  [-img <image_file_name>]\n"  
  54.                 "  [-vec <vec_file_name>]\n"  
  55.                 "  [-bg <background_file_name>]\n  [-num <number_of_samples = %d>]\n"  
  56.                 "  [-bgcolor <background_color = %d>]\n"  
  57.                 "  [-inv] [-randinv] [-bgthresh <background_color_threshold = %d>]\n"  
  58.                 "  [-maxidev <max_intensity_deviation = %d>]\n"  
  59.                 "  [-maxxangle <max_x_rotation_angle = %f>]\n"  
  60.                 "  [-maxyangle <max_y_rotation_angle = %f>]\n"  
  61.                 "  [-maxzangle <max_z_rotation_angle = %f>]\n"  
  62.                 "  [-show [<scale = %f>]]\n"  
  63.                 "  [-w <sample_width = %d>]\n  [-h <sample_height = %d>]\n"  
  64.                 "  [-pngoutput]",  
  65.                 argv[0], num, bgcolor, bgthreshold, maxintensitydev,  
  66.                 maxxangle, maxyangle, maxzangle, scale, width, height );  
  67.   
  68.         return 0;  
  69.     }  

[cpp] view plain copy print?
  1.  for( i = 1; i < argc; ++i )  
  2. {  
  3.         //strcmp(str1,str2)函数:比较两个字符串。  
  4. //相等返回0;str1>str2返回正数;str1<str2返回负数  
  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<DatasetGenerator> creator;  
  130.         if( pngoutput )  
  131.         {  
  132.             creator = std::auto_ptr<DatasetGenerator>( new PngDatasetGenerator( infoname ) );  
  133.         }  
  134.         else  
  135.         {  
  136.             creator = std::auto_ptr<DatasetGenerator>( new 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文件路径  

[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 <assert.h> 
  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
 
 

我的同类文章

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

  暂无评论

* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
核心技术类目
全部主题HadoopAWS移动游戏JavaAndroidiOSSwift智能硬件DockerOpenStackVPNSparkERPIE10EclipseCRMJavaScript数据库UbuntuNFCWAPjQueryBIHTML5SpringApache.NETAPIHTMLSDKIISFedoraXMLLBSUnitySplashtopUMLcomponentsWindows MobileRailsQEMUKDECassandraCloudStackFTCcoremailOPhoneCouchBase云计算iOS6RackspaceWeb AppSpringSideMaemoCompuware大数据aptechPerlTornadoRubyHibernateThinkPHPHBasePureSolrAngularCloud FoundryRedisScalaDjangoBootstrap
    个人资料

    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通讯相关的问题,你在吗能否回我私信?

0 0
原创粉丝点击