I am trying to run the createsamples
example from the OpenCV library. I can load in one image at a time and it seems to work fine. However, when I try to load in a collection of images I get a parse error. I am not sure if it is something in my collection file that is invalid or if I am missing something elsewhere. Below is the exact format of my text document.
Text document details:
Target1.JPG 1 0 0 1296 1152
Target2.jpg 1 0 0 1890 709
Command line call:
-info "C:\Users\seb\Desktop\Learning Samples\Target\Target.txt" -num 10 -vec "C:\Users\seb\Desktop\Learning Samples\Target\Target.vec" -maxxangle 0.6 -maxyangle 0 -maxzangle 0.3 -maxidev 100 -bgcolor 0 -bgthresh 0 -w 20 -h 20
Any help is greatly appreciated.
The parse error is because when you do not specify the number of pos image samples you want to generate, the createsamples will use the default value which is 1000. But if your annotation text document contains less than 1000 bounding boxes of objects, you will get the parse error. You can still use the .vec file for training cascade. The only problem is that the information of number is incorrect. There are two ways to fix it.
You manually count the number of object bounding boxes in the text document. And specify the value less or equal to the number for the option "-num" e.g. createsamples -info xxxxx.txt -vec pos.vec -num [value]
You can revise the OPENCV_ROOT_DIR/modules/haartraining/createsamples.cpp. When the -num is not specified, set the number of pos samples as the number of object bounding boxes in the text document
code snippet: In createsamples.cpp int num = 0;
In 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: %s\n", vecfilename );
#endif /* CV_VERBOSE */
return total;
}
info = fopen( infoname, "r" );
if( info == NULL )
{
#if CV_VERBOSE
fprintf( stderr, "Unable to open file: %s\n", infoname );
#endif /* CV_VERBOSE */
return total;
}
vec = fopen( vecfilename, "wb" );
if( vec == NULL )
{
#if CV_VERBOSE
fprintf( stderr, "Unable to open file: %s\n", 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: %s\n", 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;
}
I struggled to get opencv_createsamples
to work on my windows machine, and it just worked successfully. I thought I would post the details to help someone else. I am using opencv 2.4.8 on Windows 7
.
First, I found I needed to use the opencv_createsamples.exe
file in the directory that is listed in my path variable as OPENCV_DIR
. I could not copy the exe
file to some more convenient place.
I set up a sub directory text_classifier
in this directory for my images and my text files. I used this command on the command line:
F:\Apps\opencv\build\x64\vc10\bin>opencv_createsamples.exe -vec text_classifier\text_binary_desc -info text_classifier\positive_examples.txt -num 146 -w 1350 -h 900 -bg text_classifier\negative_samples.txt
Notice that I had to list the number of selected areas in the images (-num 146). I also listed the width and height of the positive samples.
Inside the file positive_examples.txt, I needed to have the files listed so:
text_positives_clean\1839_Boettiger_001.JPG 1 708 35 471 793
In other words, the files had to be listed relative to the file positive_examples.txt, and not relative to the exe file (opencv_createsamples.exe). When I tried listing the files relative to the exe, such as:
text_classifier\text_positives_clean\1839_Boettiger_001.JPG 1 708 35 471 793
then I got the error: Unable to open image: text_classifier\text_classifier\text_positives_clean\1839_Boettiger_001.JPG
Then I noticed that my special automated system of creating this file somehow had missed loading some files into the directory, so there were files listed in positive_examples.txt that were not in the directory. The exe simply fell over if it found something listed in positive_examples.txt that was not in the directory. I filled the gaps in the image directory.
Then I got a strange error: Unable to open image: 129
I discovered that I had made this mistake:
text_positives_clean\1862_Streckfuss_0006.JPG 1 813 502 382 353 129 46 526 798 682 780 117 67
Do you notice that the number of selected areas stated here is 1 (the number just following 'JPG'), while the number of selected areas is really 3? So opencv_createsamples.exe tried to open the next thing it found as an image, i.e. '129', after getting the single selected area. And it fell over again.
So I changed the 1 to a 3. Then I got a parse error that actually gave me a line number in my positive_examples.txt file. I went to that line, and found that one of my entries did not have a space between the selected areas, such as:
949 315 157 67131 30 513 806
I fixed this, adding the space, and finally the exe did all my 146 samples. Yoohoo!
Hope this helps someone. :-)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With