El error de análisis se debe a que, cuando no se especifica el número de muestras de imagen de punto de venta que desea generar, los createsamples utilizarán el valor predeterminado que es 1000. Pero si su documento de texto de anotación contiene menos de 1000 cuadros de objetos delimitadores, obtendrá el error de análisis. Todavía puede usar el archivo .vec para la cascada de entrenamiento. El único problema es que la información del número es incorrecta. Hay dos formas de arreglarlo.
Cuenta manualmente el número de cuadros delimitadores de objetos en el documento de texto. Y especifique el valor menor o igual que el número para la opción "-num" , p. createsamples -info xxxxx.txt -vec pos.vec -num [value]
Puede revisar OPENCV_ROOT_DIR/modules/haartraining/createsamples.cpp. Cuando no se especifica el -num, establecer el número de muestras de punto de venta como el número de cajas de objeto de delimitación en el documento de texto
fragmento de código: En createsamples.cpp int num = 0;
En 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;
}
¿Podría pasar toda la llamada de línea de comando? – red1ynx
He editado la pregunta para incluir la línea de comando como se especifica. También el archivo de texto está en el mismo directorio que las imágenes. – Seb