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

发布时间 2023-05-04 22:24:54作者: MaxBruce

原文:https://www.bilibili.com/read/cv10624306/

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文件。有不对的地方请多多包涵,有错误欢迎大家指正,谢谢。 作者:Kinect开发 https://www.bilibili.com/read/cv10624306/ 出处:bilibili