我正在尝试从OpenCV库运行createsamples
示例。我可以一次加载一个图像,看起来效果不错。然而,当我尝试加载一组图像时,会出现解析错误。我不确定我的收藏文件中是否有无效的东西,或者我在其他地方遗漏了什么。以下是我的文本文件的确切格式。
文本文档详细信息:
Target1.JPG 1 0 0 1296 1152
Target2.jpg 1 0 0 1890 709
命令行呼叫:
-info "C:UserssebDesktopLearning SamplesTargetTarget.txt" -num 10 -vec "C:UserssebDesktopLearning SamplesTargetTarget.vec" -maxxangle 0.6 -maxyangle 0 -maxzangle 0.3 -maxidev 100 -bgcolor 0 -bgthresh 0 -w 20 -h 20
非常感谢您的帮助。
解析错误是因为当您没有指定要生成的pos图像样本的数量时,createsamples将使用默认值1000。但是,如果注释文本文档包含的对象边界框少于1000个,则会出现解析错误。您仍然可以使用.vc文件进行级联训练。唯一的问题是号码的信息不正确。有两种方法可以修复它。
-
您可以手动计算文本文档中对象边界框的数量。并指定小于或等于选项"-num"的数字的值例如createsamples-info xxxxx.txt-vc pos-vec-num[value]
-
您可以修改OPENCV_ROOT_DIR/modules/haartraining/createsamples.cpp。如果未指定-num,则将pos样本的数量设置为文本文档中对象边界框的数量
代码段:在createsamples.cpp中int num=0;
在cvsamples.cpp 中
void icvWriteVecHeader( FILE* file, int count, int width, int height )
{
int vecsize;
short tmp;
fseek ( file , 0 , SEEK_SET );
/* 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 );
fseek ( file , 0 , SEEK_END );
}
int cvCreateTrainingSamplesFromInfo( const char* infoname, const char* vecfilename,
int num,
int showsamples,
int winwidth, int winheight )
{
char fullname[PATH_MAX];
char* filename;
FILE* info;
FILE* vec;
IplImage* src=0;
IplImage* sample;
int line;
int error;
int i;
int x, y, width, height;
int total;
assert( infoname != NULL );
assert( vecfilename != NULL );
total = 0;
if( !icvMkDir( vecfilename ) )
{
#if CV_VERBOSE
fprintf( stderr, "Unable to create directory hierarchy: %sn", vecfilename );
#endif /* CV_VERBOSE */
return total;
}
info = fopen( infoname, "r" );
if( info == NULL )
{
#if CV_VERBOSE
fprintf( stderr, "Unable to open file: %sn", infoname );
#endif /* CV_VERBOSE */
return total;
}
vec = fopen( vecfilename, "wb" );
if( vec == NULL )
{
#if CV_VERBOSE
fprintf( stderr, "Unable to open file: %sn", vecfilename );
#endif /* CV_VERBOSE */
fclose( info );
return total;
}
sample = cvCreateImage( cvSize( winwidth, winheight ), IPL_DEPTH_8U, 1 );
icvWriteVecHeader( vec, num, sample->width, sample->height );
if( showsamples )
{
cvNamedWindow( "Sample", CV_WINDOW_AUTOSIZE );
}
strcpy( fullname, infoname );
filename = strrchr( fullname, '\' );
if( filename == NULL )
{
filename = strrchr( fullname, '/' );
}
if( filename == NULL )
{
filename = fullname;
}
else
{
filename++;
}
while ( num<=0 || total<num )
{
int count;
error = ( fscanf( info, "%s %d", filename, &count ) != 2 );
if( !error )
{
src = cvLoadImage( fullname, 0 );
error = ( src == NULL );
if( error )
{
#if CV_VERBOSE
fprintf( stderr, "Unable to open image: %sn", fullname );
#endif /* CV_VERBOSE */
}
}
else
if ( num <= 0 ) break;
for( i = 0; i < count; i++, total++ )
{
error = ( fscanf( info, "%d %d %d %d", &x, &y, &width, &height ) != 4 );
if( error ) break;
cvSetImageROI( src, cvRect( x, y, width, height ) );
cvResize( src, sample, width >= sample->width &&
height >= sample->height ? CV_INTER_AREA : CV_INTER_LINEAR );
if( showsamples )
{
cvShowImage( "Sample", sample );
if( cvWaitKey( 0 ) == 27 )
{
showsamples = 0;
}
}
icvWriteVecSample( vec, sample );
if ( num > 0 && total >= num ) break;
}
if ( num<=0 )
icvWriteVecHeader( vec, total, sample->width, sample->height );
if( src )
{
cvReleaseImage( &src );
}
if( error )
{
#if CV_VERBOSE
fprintf( stderr, "%s(%d) : parse error", infoname, line );
#endif /* CV_VERBOSE */
break;
}
}
if( sample )
{
cvReleaseImage( &sample );
}
fclose( vec );
fclose( info );
return total;
}
我很难让opencv_createsamples
在我的windows机器上工作,它只是成功地工作了。我想我会发布详细信息来帮助其他人。我正在使用opencv 2.4.8 on Windows 7
。
首先,我发现我需要使用路径变量OPENCV_DIR
中列出的目录中的opencv_createsamples.exe
文件。我无法将exe
文件复制到更方便的地方。
我在这个目录中为我的图像和文本文件设置了一个子目录text_classifier
。我在命令行上使用了这个命令:
F: \Apps\opencv\build\x64\vc10\bin>opencv_createsamples.exe-vectext_classifier\text_binary_desc-信息text_classifier\positive_examples.txt-num 146-w 1350-h 900-bgtext_classifier\negative_samples.txt
请注意,我必须列出图像中所选区域的数量(-num 146)。我还列出了阳性样本的宽度和高度。
在positive_examples.txt文件中,我需要列出以下文件:
text_positives_clean\1839_Boettiger_001.JPG 1 708 35 471 793
换句话说,这些文件必须相对于文件positive_examples.txt列出,而不是相对于exe文件(opencv_createsamples.exe)列出
text_classifier\text_positives_clean\1839_Boettiger_001.JPG 1 708 35 471 793
然后我得到了错误:无法打开图像:text_classifier\text_classfier\text_positives_clean\1839_Boettiger_001.JPG
然后我注意到,我创建这个文件的特殊自动化系统不知何故错过了将一些文件加载到目录中,所以positive_examples.txt中列出的文件不在目录中。如果exe发现positive_examples.txt中列出的内容不在目录中,它就会崩溃。我填补了图像目录中的空白。
然后我得到了一个奇怪的错误:无法打开图像:129
我发现我犯了一个错误:
text_positives_clean\1862_Streckfuss_0006.JPG 1 813 502 382 353 129 46526 798 682 780 117 67
你注意到这里所说的选定区域的数量是1("JPG"后面的数字),而选定区域的数目实际上是3吗?因此,opencv_createsamples.exe在获得单个选定区域后,试图打开它发现的下一个图像,即"129"。然后它又掉了下来。
所以我把1改成了3。然后我得到了一个解析错误,它实际上在positive_examples.txt文件中给了我一个行号。我走到那一行,发现我的一个条目在所选区域之间没有空格,例如:
949 315 157 67131 30 513 806
我修复了这个问题,添加了空格,最后exe完成了我所有的146个样本。Yoohoo!
希望这能帮助到别人。:-)
其中一个原因可能是因为信息文件。
/主页/地雷/人脸检测器图像/阳性/*.jpg
请确保任何文件夹名称的名称中都不应有空格。就像上面显示的"人脸检测器图像",这应该是一些其他的名字,比如"图像"或任何没有空间的东西
重命名文件夹的原始路径以及.info文件中的文件夹。
干杯!!
Target1.JPG
-它必须是createsamples.exe的相对路径。而不是Target.txt。
我在我的机器上测试过,得到了这样的结果:
d:ProgramsOpenCV-2.2.0msvs-buildbinRelease>opencv_createsamples.exe -info "d:ProgramsOpenCV-2.2.0msvs-buildbinReleaseTarget.dat" -num 10 -vec "d:ProgramsOpenCV-2.2.0msvs-buildbinReleaseTarget.vec" -maxxangle 0.6 -maxyangle 0 -maxzangle 0.3 -maxidev 100 -bgcolor 0 -bgthresh 0 -w 20 -h 20
Info file name: d:ProgramsOpenCV-2.2.0msvs-buildbinReleaseTarget.dat
Img file name: (NULL)
Vec file name: d:ProgramsOpenCV-2.2.0msvs-buildbinReleaseTarget.vec
BG file name: (NULL)
Num: 10
BG color: 0
BG threshold: 0
Invert: FALSE
Max intensity deviation: 100
Max x angle: 0.6
Max y angle: 0
Max z angle: 0.3
Show samples: FALSE
Width: 20
Height: 20
Create training samples from images collection...
d:ProgramsOpenCV-2.2.0msvs-buildbinReleaseTarget.dat(3) : parse errorDone. **Created 2 samples**