总结在训练自己的检测器中遇到的问题及解决方法:
> 1.出现unspecified error <vec file sample size mismatch>
对于我而言,我是马虎的将负样本生成的目录文件名写错了;
还有就是要注意正负样本的个数,一定要比实际文件夹下的数量少;
2.训练途中突然停止,出现OpenCV Error: Assertion failed (elements_read == 1) in icvGetHaarTraininDataFromVecCallback,file..\opencv\apps\haartraining\cvhaartraining.cpp, line 1861”
正负样本的数目,要比实际小一些,即-npos 和 -nneg后的参数设置要比实际值小些。当把npos设置与vec中总样本数相同时,第二个强分类器训练时,必然就会报错,提示样本数不足。
3.训练到某一层以后不再向下进行,如下图所示:
原因:负样本数目数量不足,找不到误检测的负样本,已经没有负样本能够进入下一层进行训练。
解决方法:
1.增加负样本的数量,增大负样本之间的变化;
2.使用convert_cascade.exe,提供下载链接: convert_cascade.exe
也可以根据源码,进行编译,在项目下,找到exe,也可以。
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <ctype.h>
#include <stdio.h>
void help()
{
printf("\n This sample demonstrates cascade's convertation \n"
"Usage:\n"
"./convert_cascade --size=\"<width>x<height>\"<convertation size> \n"
" input_cascade_path \n"
" output_cascade_filename\n"
"Example: \n"
"./convert_cascade --size=640x480 ../../opencv/data/haarcascades/haarcascade_eye.xml ../../opencv/data/haarcascades/test_cascade.xml \n"
);
}
int main( int argc, char** argv )
{
const char* size_opt = "--size=";
char comment[1024];
CvHaarClassifierCascade* cascade = 0;
CvSize size;
help();
if( argc != 4 || strncmp( argv[1], size_opt, strlen(size_opt) ) != 0 )
{
help();
return -1;
}
sscanf( argv[1], "--size=%ux%u", &size.width, &size.height );
cascade = cvLoadHaarClassifierCascade( argv[2], size );
if( !cascade )
{
fprintf( stderr, "Input cascade could not be found/opened\n" );
return -1;
}
sprintf( comment, "Automatically converted from %s, window size = %dx%d", argv[2], size.width, size.height );
cvSave( argv[3], cascade, 0, comment, cvAttrList(0,0) );
return 0;
}
#ifdef _EiC
main(1,"facedetect.c");
#endif
而后,先用cmd命令,进入到生成的训练结果的父目录,也就是opencv_haartraining.exe
的同级目录下,
然后使用命令:
convert_cascade.exe --size="20x20" G:\traing_new_cascade2 G:\traing_new_cascade2\face_detect.xml
这里: size是正样本图片像素大小;
然后: 源目录,即训练结果目录
接下来: 目标目录及生成的xml文件名
即可生成face_detect.xml,接下来用其检测即可。