OpenCV3训练人脸检测分类器生成XML文件的过程

OpenCV训练自己的分类器
注:本文举得是一个训练人脸分类器的例子,亲自试验过,采用的是opencv3.4
1.准备训练样本
看网上说正负样本比例为1:3最佳;尺寸为20x20最佳
附上人脸训练的数据集的下载链接:https://pan.baidu.com/s/1AxoIMFycfpeIMtDYHz4RBw
提取码:rap7
1.1 正样本
训练样本的尺寸为20*20(opencv推荐的最佳尺寸),且所有样本的尺寸必须一致。如果不一致的或者尺 寸较大的,可以先将所有样本统一缩放到20x20。以下是提供的正样本:
在这里插入图片描述
1.2 负样本
负样本中不存在正样本的内容,根据不同的项目选择不同的负样本,根据自己的情况而定。这里选取的负样本尺寸是50x50。以下是负样本:
在这里插入图片描述
2.构建工作目录
新建一个文件夹(名为face),在此文件夹下新建posdata,negdata,xml三个文件夹。
posdata目录:放正样本的目录
negdata目录:放负样本的目录
xml目录:生成的分类器的存放
2.1 有关文件及数据的拷贝
将下列的文件目录拷贝到face文件夹中,如图:
在这里插入图片描述
在这里插入图片描述
接着将人脸的正负样本分别拷贝到posdata和negdata文件夹中。

2.2 生成样本描述文件
1.在negdata文件夹中建立一个neg.txt文件,在此txt文件中输入:dir /b/s/p/w *.jpg > neg.txt
然后保存,将neg.txt更改为neg.bat,接着双击neg.bat,就会生成neg.txt,以下为里面的内容:
在这里插入图片描述
2.在posdata文件夹中建立一个pos.txt文件,在此txt文件中输入:dir /b/s/p/w *.jpg > pos.txt
然后保存,将pos.txt更改为pos.bat,接着双击pos.bat,就会生成pos.txt,以下为里面的内容:
在这里插入图片描述
接着将jpg 替换为jpg 1 0 0 20 20(数字分别代表为:数量,起点坐标:0,0 大小:20x20),点击编辑,
在这里插入图片描述
在这里插入图片描述
内容变成以下这样即可
在这里插入图片描述3.训练样本
3.1生成.vec文件
将pos.txt和neg.txt拷贝到face文件夹下,然后在face文件夹打开终端(shift+右键),在终端依次输入:
opencv_createsamples.exe -vec pos.vec -info pos.txt -num 18500 -w 20 -h 20
opencv_createsamples.exe -vec neg.vec -info neg.txt -num 10925 -w 50 -h 50
即可生成.vec文件。
说明:

-info,指样本说明文件

-vec,样本描述文件的名字及路径

-num,总共几个样本,要注意,这里的样本数是指标定后的20x20的样本数,而不是大图的数目,其实就是样本说明文件第2列的所有数字累加

-w -h指明想让样本缩放到什么尺寸。这里的奥妙在于你不必另外去处理第1步中被矩形框出的图片的尺寸,因为这个参数帮你统一缩放!(我们这里准备的样本都是20*20)
在这里插入图片描述
3.2训练样本
新建txt文件,把
opencv_traincascade.exe -data xml -vec pos.vec -bg neg.txt -numPos 500 -numNeg 656 -numStages 20 -w 20 -h 20 -mode ALL

pause
复制进去保存,并将文件名修改为traincascade.bat,最后双击该文件即可,剩下的就是等待了,在xml会生成cascade.xml,这个就是我们训练得到的分类器。
在这里插入图片描述
xml目录下的cascade.xml就是我们需要的分类器,将其拷进需要运用的工程目录下即可。在这里插入图片描述
4.使用VS2015编写测试程序
注意:分类器需放在工程文件下!!
测试代码如下:

#include “stdafx.h”
#include 
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;
int main()
{
//加载Haar或LBP对象或人脸检测器
CascadeClassifier faceDetector; 
std::string faceCascadeFilename = “cascade.xml”;

//友好错误信息提示
try {
	faceDetector.load(faceCascadeFilename);
}
catch (cv::Exception e) {}
if (faceDetector.empty())
{
	std::cerr << "人脸检测器不能加载 (";
	std::cerr << faceCascadeFilename << ")!" << std::endl;
	exit(1);
}
//打开摄像头
VideoCapture camera(0);
Mat camerFrame, gray;
while (1)
{
	camera >> camerFrame;
	cvtColor(camerFrame, gray, COLOR_BGR2GRAY);
	//直方图均匀化(改善图像的对比度和亮度)
	Mat equalizedImg;
	equalizeHist(gray, equalizedImg);

	//人脸检测
	std::vector<Rect> faces;
	faceDetector.detectMultiScale(equalizedImg, faces, 1.1f, 15, CASCADE_FIND_BIGGEST_OBJECT, Size(30,30));
	//画矩形框
	for (size_t i = 0; i < faces.size(); i++)
	{
		if (faces[i].height > 0 && faces[i].width > 0)
		{
			cv::rectangle(camerFrame, faces[i], cv::Scalar(255, 0, 0), 1, 8, 0);     //Scalar绘制的颜色,分别是R,G,B

		}
	}

	imshow("原图", camerFrame);
	waitKey(20);
}
  •  

}
然后调试运行:
在这里插入图片描述
总结:由于在上面训练的样本选太少了,训练出来的效果不太好,识别不佳,而且训练几百张图片,花了好几个小时,电脑太垃圾了,没有OpenCV自带的人脸检测的文件那么好,但是总算知道了如何自己训练出XML文件。有不对的地方请多多包涵,有错误欢迎大家指正,谢谢。
在这里插入图片描述
最后感谢两位博主:
https://blog.csdn.net/Coulson_Zhao/article/details/80980408
https://blog.csdn.net/qq_32502511/article/details/79010509

  • 6
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值