做项目的时候使用到了OpenCV自带的haartraining训练器。在这片文章中就针对其进行使用进行说明,希望对各位看官有用。
这里首先采集到未经处理的原始样本集,通过手工标注或是截取的形式得到正样本集。对正样本集进行标准化,这里生成的是30*30大小的正样本图像,这样主要为了加快训练的速度。得到的正样本集如下
之后在当前目录下打开命令行窗口,将正样本的路径导入到pos.txt文件中去
dir /s/b > pos.txt
生成文件之后需要对文件进行标记指定目标的个数、区域的起始XY坐标、宽度、高度
调用opencv_createsamples.exe生成样本集
opencv_createsamples.exe -vec pos.vec -info pos.txt -num 10 -w 30 -h 30
上面命令行参数解释为:通过pos.txt提供的路径生成30*30图像大小块的正样本集pos.vec。这里顺带说明一下opencv_createsamples.exe程序的命令行参数:
-info 描述物体所在图像以及大小位置的描述文件。
-vec 输出文件,内含用于训练的正样本。
-img 输入图像文件名(例如一个公司的标志)。
-bg背景图像的描述文件,文件中包含一系列的图像文件名,这些图像将被随机选作物体的背景。
-num生成的正样本的数目。
-bgcolor背景颜色(目前为灰度图);背景颜色表示透明颜色。因为图像压缩可造成颜色偏差,颜色的容差可以由-bgthresh指定。所有处于bgcolor-bgthresh和bgcolor+bgthresh之间的像素都被设置为透明像素。
-bgthresh
-inv如果指定该标志,前景图像的颜色将翻转。
-randinv如果指定该标志,颜色将随机地翻转。
-maxidev前景样本里像素的亮度梯度的最大值。
-maxxangle X轴最大旋转角度,必须以弧度为单位。
-maxyangle Y轴最大旋转角度,必须以弧度为单位。
-maxzangleZ轴最大旋转角度,必须以弧度为单位。
-show很有用的调试选项。如果指定该选项,每个样本都将被显示。如果按下Esc键,程序将继续创建样本但不再显示。
-w输出样本的宽度(以像素为单位)。
-h输出样本的高度(以像素为单位)。
对于负样本集并不要求样本的尺寸都是完全相同的,但是要大于正样本的大小。负样本不能有重复的,且增大负样本的差异性。这里对负样本只进行了灰度化处理。
处理完负样本图像之后,也需要生成负样本目录文件
dir /s/b > neg.txt
前面已经收集好了正样本和负样本,接下来就可以使用训练器进行训练了
opencv_haartraining.exe -data out -vec pos.vec -bg neg.txt -nstages 10 -nsplits 1 -npos 10 -nneg 100 -mem 1280 -mode all -w 30 -h 30
说一下这些参数的含义
1.通用参数:
-data 目录名,如不存在训练程序会创建它,用于存放训练好的分类器。
-vec 包含正样本的vec文件名(由opencv_createsamples程序生成)。
-bg 背景描述文件,也就是包含负样本文件名的那个描述文件。
-numPos 每级分类器训练时所用的正样本数目。
-numNeg 每级分类器训练时所用的负样本数目,可以大于 -bg 指定的图片数目。
-numStages 训练的分类器的级数。
-precalcValBufSize缓存大小,用于存储预先计算的特征值(feature values),单位为MB。
-precalcIdxBufSize缓存大小,用于存储预先计算的特征索引(feature indices),单位为MB。内存越大,训练时间越短。
-baseFormatSave这个参数仅在使用Haar特征时有效。如果指定这个参数,那么级联分类器将以老的格式存储。
2.级联参数:
-stageType <BOOST(default)>级别(stage)参数。目前只支持将BOOST分类器作为级别的类型。
-featureType<{HAAR(default), LBP}>特征的类型: HAAR - 类Haar特征; LBP - 局部纹理模式特征。
-w
-h 训练样本的尺寸(单位为像素)。必须跟训练样本创建(使用 opencv_createsamples 程序创建)时的尺寸保持一致。
3.分类器参数:
-bt <{DAB, RAB, LB,GAB(default)}> Boosted分类器参数:
DAB - Discrete AdaBoost, RAB - Real AdaBoost, LB - LogitBoost, GAB -Gentle AdaBoost。Boosted分类器的类型:
-minHitRate分类器的每一级希望得到的最小检测率。总的检测率大约为n_hit_rate^number_of_stages。
-maxFalseAlarmRate分类器的每一级希望得到的最大误检率。总的误检率大约为 max_false_alarm_rate^number_of_stages.
-weightTrimRate Specifies whether trimmingshould be used and its weight.一个还不错的数值是0.95。
-maxDepth 弱分类器树最大的深度。一个还不错的数值是1,是二叉树(stumps)。
-maxWeakCount每一级中的弱分类器的最大数目。The boostedclassifier (stage) will have so many weak trees (<=maxWeakCount), as neededto achieve the given -maxFalseAlarmRate.
4.类Haar特征参数:
-mode <BASIC (default) |CORE | ALL>选择训练过程中使用的Haar特征的类型。 BASIC 只使用右上特征, ALL使用所有右上特征和45度旋转特征。
5.LBP特征参数:
LBP特征无参数。
训练完成之后看到的就是最重要的XML文件了,用作后面分类使用
这里就直接贴出目标检测的代码了
//根据提供的XML去检测目标图像是否包含需要的结果
bool ObjectDetectShow(std::string xml_path, std::string testpic_path)
{
cv::CascadeClassifier Mycascade;
if (!Mycascade.load(xml_path))
{
cout << "[error] 无法加载级联分类器文件!" << endl;
return false;
}
cv::Mat image = cv::imread(testpic_path, 0);//读取图片
if (!image.data)
{
cout << "[error] 没有图片" << endl;
return false;
}
std::vector pedestrain;
cv::Mat frame_gray = image;
Mycascade.detectMultiScale(frame_gray, pedestrain, 1.1, 3, 0, cv::Size(20, 20));
for (unsigned int i = 0; i < pedestrain.size(); i++)
{
rectangle(image, pedestrain[i], cv::Scalar(0, 255, 0), 1); //画出目标的矩形区域
//接下来还需要有对这些检测出来的区域进行进一步甄别的代码,此处省略...
}
cv::imshow("result", image);
cv::waitKey(0);
return true;
}
检测函数参数说明
void CascadeClassifier::detectMultiScale(const Mat& image, —Mat类型的图像
vector & objects, —检测得到的矩形
double scaleFactor, —图像缩放因子,必须大于1
int minNeighbors, —构成检测目标的相邻矩形的最小个数
int flags, —旧分类器使用,新分类器弃用
Size minObjectSize, —最小检测窗口大小
Size maxObjectSize) —最大检测窗口大小(默认是图像大小)