第一步:准备好正负样本图片,正样本就是含有目标的图片,负样本就是不含有目标的图片,建好文件夹(如下图所示)。其中正样本图片最好是裁剪成同一尺寸,我这里是建成28*28,便于后期的说明文件的建立。
第二步:生成文件名列表
aa.bat 为批量生成文件名的程序(大家可以建个文本输入下面的内容就可制作,“.bat”结尾)
使用的时候只需要连击两下bat这个文件就能生成一个.txt 的文件,里面是当前目录下的文件名,删除里面不是图像的文件名
neg->负样本
pos->正样本
下图为neg 文件夹里面的内容以及txt的内容
下图为pos的文件夹以及txt的内容
第三步:生成训练样本
下图为生成训练样本的程序(当然opencv_createsamples.exe 在opencv /build/x86/vc10/bin里面,我放在了D盘根目录下)
利用opencv_createsamples.exe应用程序在该目录下使用如图cmd命令:
其中的-vec是指定后面输出vec文件的文件名,-info指定正样本描述文件,-bg指定负样本描述文件,-w和-h分别指正样本的宽和高,-num表示正样本的个数。执行完该命令后就会在当前目录下生产一个pos.vec文件了。
成功的话效果如下:
第四步:训练
首先在当前目录下新建一个dt文件夹用于存放生成的.xml文件。
在当前目录使用cmd命令:
D:\>opencv_traincascade.exe -data dt -vec pos.vec -bg neg/neg.txt -numPos 100 -n
umNeg 300 -numStages 5 -precalcValbufSize 200 -precalcdxBufSize 1000 -featureTy
pe HOG -w 28 -h 28截图如下:其中-data 输出目录,-numPos正样本数目-numNeg负样本数目-numStages训练级数
训练成功结果如下图:
这里附上简单的测试程序
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/ml/ml.hpp"
#include <iostream>
using namespace std;
using namespace cv;
string cascadeName = "cascade.xml";//训练数据
int main( )
{
CascadeClassifier cascade;//创建级联分类器对象
vector<Rect> rects;
vector<Rect>::const_iterator pRect;
double scale = 1.;
Mat image;
double t;
if( !cascade.load( cascadeName ) )//从指定的文件目录中加载级联分类器
{
cerr << "ERROR: Could not load classifier cascade" << endl;
return 0;
}
Mat gray, smallImg;
string filename = "图片路径";
image = imread(filename);
cvtColor( image, smallImg, CV_BGR2GRAY );//灰度转换
rects.clear();
printf( "begin...\n");
t = (double)cvGetTickCount();//用来计算算法执行时间
vector<int> level;
vector<double> reject;
cascade.detectMultiScale(smallImg,rects,1.1,3,0,Size(30,30),Size(100,100));//这里可能某些数据需要修改
t = (double)cvGetTickCount() - t;
printf( "detection time = %g ms\n\n", t/((double)cvGetTickFrequency()*1000.) );
for(pRect = rects.begin(); pRect != rects.end(); pRect++)
{
rectangle(image,cvPoint(pRect->x,pRect->y),cvPoint(pRect->x+pRect->width,pRect->y+pRect->height),cvScalar(0,255,0));
}
imwrite("1.jpg",image);
waitKey();
return 0;
}