转载自https://blog.csdn.net/xbcReal/article/details/77644956
opencv_createsamples用到了以下几个源码文件,分别是/home/xbc/opencv-2.4.13/apps/haartraining/createsamples.cpp以及/home/xbc/opencv-2.4.13/apps/haartraining/cvsamples.cpp,其中主函数在第一个文件之中。
createsamples.cpp的源码如下:
#include
#include
#include
#include
#include
#include
using namespace std;
#include "cvhaartraining.h"
#include "ioutput.h"
int main( int argc, char* argv[] )
{
int i = 0;
char* nullname = (char*)"(NULL)";
char* vecname = NULL; /* .vec file name */
char* infoname = NULL; /* file name with marked up image descriptions */
char* imagename = NULL; /* single sample image */
char* bgfilename = NULL; /* background */
int num = 1000;
int bgcolor = 0;
int bgthreshold = 80;
int invert = 0;
int maxintensitydev = 40;
double maxxangle = 1.1;
double maxyangle = 1.1;
double maxzangle = 0.5;
bool showsamples = false;
/* the samples are adjusted to this scale in the sample preview window */
double scale = 4.0;
int width = 24;
int height = 24;
bool pngoutput = false; /* whether to make the samples in png or in jpg*/
srand((unsigned int)time(0));
//解析命令行参数的代码
if( argc == 1 )
{
printf( "Usage: %s\n [-info ]\n"
" [-img ]\n"
" [-vec ]\n"
" [-bg ]\n [-num ]\n"
" [-bgcolor ]\n"
" [-inv] [-randinv] [-bgthresh ]\n"
" [-maxidev ]\n"
" [-maxxangle ]\n"
" [-maxyangle ]\n"
" [-maxzangle ]\n"
" [-show []]\n"
" [-w ]\n [-h ]\n"
" [-pngoutput]",
argv[0], num, bgcolor, bgthreshold, maxintensitydev,
maxxangle, maxyangle, maxzangle, scale, width, height );
return 0;
}
for( i = 1; i < argc; ++i )
{
if( !strcmp( argv[i], "-info" ) )
{
infoname = argv[++i];
}
else if( !strcmp( argv[i], "-img" ) )
{
imagename = argv[++i];
}
else if( !strcmp( argv[i], "-vec" ) )
{
vecname = argv[++i];
}
else if( !strcmp( argv[i], "-bg" ) )
{
bgfilename = argv[++i];
}
else if( !strcmp( argv[i], "-num" ) )
{
num = atoi( argv[++i] );
}
else if( !strcmp( argv[i], "-bgcolor" ) )
{
bgcolor = atoi( argv[++i] );
}
else if( !strcmp( argv[i], "-bgthresh" ) )
{
bgthreshold = atoi( argv[++i] );
}
else if( !strcmp( argv[i], "-inv" ) )
{
invert = 1;
}
else if( !strcmp( argv[i], "-randinv" ) )
{
invert = CV_RANDOM_INVERT;
}
else if( !strcmp( argv[i], "-maxidev" ) )
{
maxintensitydev = atoi( argv[++i] );
}
else if( !strcmp( argv[i], "-maxxangle" ) )
{
maxxangle = atof( argv[++i] );
}
else if( !strcmp( argv[i], "-maxyangle" ) )
{
maxyangle = atof( argv[++i] );
}
else if( !strcmp( argv[i], "-maxzangle" ) )
{
maxzangle = atof( argv[++i] );
}
else if( !strcmp( argv[i], "-show" ) )
{
showsamples = true;
if( i+1 < argc && strlen( argv[i+1] ) > 0 && argv[i+1][0] != '-' )
{
double d;
d = strtod( argv[i+1], 0 );
if( d != -HUGE_VAL && d != HUGE_VAL && d > 0 ) scale = d;
++i;
}
}
else if( !strcmp( argv[i], "-w" ) )
{
width = atoi( argv[++i] );
}
else if( !strcmp( argv[i], "-h" ) )
{
height = atoi( argv[++i] );
}
else if( !strcmp( argv[i], "-pngoutput" ) )
{
pngoutput = true;
}
}
printf( "Info file name: %s\n", ((infoname == NULL) ? nullname : infoname ) );
printf( "Img file name: %s\n", ((imagename == NULL) ? nullname : imagename ) );
printf( "Vec file name: %s\n", ((vecname == NULL) ? nullname : vecname ) );
printf( "BG file name: %s\n", ((bgfilename == NULL) ? nullname : bgfilename ) );
printf( "Num: %d\n", num );
printf( "BG color: %d\n", bgcolor );
printf( "BG threshold: %d\n", bgthreshold );
printf( "Invert: %s\n", (invert == CV_RANDOM_INVERT) ? "RANDOM"
: ( (invert) ? "TRUE" : "FALSE" ) );
printf( "Max intensity deviation: %d\n", maxintensitydev );
printf( "Max x angle: %g\n", maxxangle );
printf( "Max y angle: %g\n", maxyangle );
printf( "Max z angle: %g\n", maxzangle );
printf( "Show samples: %s\n", (showsamples) ? "TRUE" : "FALSE" );
if( showsamples )
{
printf( "Scale applied to display : %g\n", scale );
}
if( !pngoutput)
{
printf( "Original image will be scaled to:\n");
printf( "\tWidth: $backgroundWidth / %d\n", width );
printf( "\tHeight: $backgroundHeight / %d\n", height );
}
//解析命令行参数的代码到此结束
/* determine action */
//根据输入的是描述待检测物体的info文件还是一张图像的名字文件执行不同的操作,一般我们在网上找到的教程多是根据info.dat或者info.txt来创建samples的,创建samples的例子可以参考:
http://www.cnblogs.com/easymind223/archive/2012/07/03/2574826.html,因此我们这里只查看下面的if语句中的“else if( infoname && vecname )”
//我们不关注这部分代码
if( imagename && vecname )
{
printf( "Create training samples from single image applying distortions...\n" );
cvCreateTrainingSamples( vecname, imagename, bgcolor, bgthreshold, bgfilename,
num, invert, maxintensitydev,
maxxangle, maxyangle, maxzangle,
showsamples, width, height );
printf( "Done\n" );
}
//我们不关注这部分代码
else if( imagename && bgfilename && infoname)
{
printf( "Create data set from single image applying distortions...\n"
"Output format: %s\n",
(( pngoutput ) ? "PNG" : "JPG") );
std::auto_ptr creator;
if( pngoutput )
{
creator = std::auto_ptr( new PngDatasetGenerator( infoname ) );
}
else
{
creator = std::auto_ptr( new JpgDatasetGenerator( infoname ) );
}
creator->create( imagename, bgcolor, bgthreshold, bgfilename, num,
invert, maxintensitydev, maxxangle, maxyangle, maxzangle,
showsamples, width, height );
printf( "Done\n" );
}
//我们关注这部分代码,因为这里使用了info文件创建.vec文件,是我们常见的方法
else if( infoname && vecname )
{
int total;
printf( "Create training samples from images collection...\n" );
//在这里真正地创建了.vec文件
total = cvCreateTrainingSamplesFromInfo( infoname, vecname, num, showsamples,
width, height );
printf( "Done. Created %d samples\n", total );
}
//我们不关注这部分代码
else if( vecname )
{
printf( "View samples from vec file (press ESC to exit)...\n" );
cvShowVecSamples( vecname, width, height, scale );
printf( "Done\n" );
}
else
{
printf( "Nothing to do\n" );
}
return 0;
}
void icvWriteVecHeader( FILE* file, int count, int width, int height )
{
int vecsize;
short tmp;
/* number of samples */
fwrite( &count, sizeof( count ), 1, file );
/* vector size */
vecsize = width * height;
fwrite( &vecsize, sizeof( vecsize ), 1, file );
/* min/max values */
tmp = 0;
fwrite( &tmp, sizeof( tmp ), 1, file );
fwrite( &tmp, sizeof( tmp ), 1, file );
}
void icvWriteVecSample( FILE* file, CvArr* sample )
{
CvMat* mat, stub;
int r, c;
short tmp;
uchar chartmp;
mat = cvGetMat( sample, &stub );
chartmp = 0;
fwrite( &chartmp, sizeof( chartmp ), 1, file );
for( r = 0; r < mat->rows; r++ )
{
for( c = 0; c < mat->cols; c++ )
{
tmp = (short) (CV_MAT_ELEM( *mat, uchar, r, c ));
fwrite( &tmp, sizeof( tmp ), 1, file );
}
}
}
至此opencv_createsamples的源码文件就解析完毕了,读完源码还意识到对于使用info文件创建.vec文件的方法来说,-bg这个参数根本用不到,之前我在自己利用info文件创建.vec文件的时候还有将这个-bg的参数填为存储负样本名字的文件名,事实上这是多余的。