提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

使用级联分类器训练人脸模型

项目场景:


作为一个大四狗,在毕业之前想做点有意思的东西,加上人工智能这两年很火,也就从网上找资源,进行了一个学习的过程,使用的平台是QT5.12+OpenCV3.40。目的就是为了训练一个可以进行人脸检测的模型。

正样本准备:

跟着贾志刚老师的课程学了一段时间以后,自己也就找项目去练手去了。不过在训练的过程中还是借鉴了大佬的博客
里面的描述还是很详细的。采集的方法有了,但是数据方面也是很重要的,为此,我写了一个QT的应用程序来进行数据采集的工作。` string writePath = “E:/Trainslation/img/”;
VideoCapture capture(1);
string name;
Mat Gray,outs;
int i = 939 ;
Rect rect(0,0,300,300);
capture.set(CAP_PROP_FRAME_WIDTH, 540.0);
//设置摄像头采集图像分辨率
capture.set(CAP_PROP_FRAME_HEIGHT, 680.0);
while(1){
Mat frame;
capture>>frame;
if(32==waitKey(20))
{
name = writePath + to_string(i)+".jpg";
outs = Mat(frame,rect);
cvtColor(outs,Gray,COLOR_BGR2GRAY);
imwrite(name,frame);
cout<<name<<endl;
i++;
}
if (97 == waitKey(10)) { //'a’退出
break;
}
rectangle(frame,rect,Scalar(125,125,125),3,LINE_8,0);
imshow(“hello”,frame);
//imshow(“GRAY”,Gray);
}

运行结果图:

OpenCVFrameConverter 人脸识别 m3u8_深度学习


方框里面的就是图像采集区域,可以通过修改Rect参数来控制范围,通过按下空格进行拍照,讲目标图片存入指定的位置。

OpenCVFrameConverter 人脸识别 m3u8_opencv_02


通过对实验室的小学弟进行友好互动,得到了近500张人脸的样本,因为对正样本的要求是要灰度图片,所以在采集的时候做了灰度转换处理。

cvtColor(outs,Gray,COLOR_BGR2GRAY);//灰度转换

负样本准备:

对于负样本的要求很简单的,只需要不包含正样本的照片就可以的了,当然负样本数量跟正样本数量的比例约为3:1。

从网上找了一些图片,还有就是使用上面的素材采样程序,通过加大开窗,以及取消灰度转换,得到了近1500张的负样本素材。

OpenCVFrameConverter 人脸识别 m3u8_机器学习_03

分类器样本制作:

制作方法很简单,首先就是在采集到的图像的路径下面通过记事本创建一个.txt文件。输入以下内容:
dir /b/s/p/w *.jpg > positives.txt
这个正样本使用相对路径即可,打开记事本讲路径进行替换
face\0.jpg 1 0 0 100 100
保留为前面的face\即可,后面的.jpg替换为.jpg 1 0 0 100 100
注意后面的100 100 是图片的长度和宽度,这个根据需求自行改变
最后将生产的txt文件后缀改为.bat格式。然后将这个文件剪切到上一级路径上。
同理,负样本也是可以通过这种方法来进行制作,但是.jpg 后面的内容是可以省略的。

opencv配置:

在正式训练之前我们需要将opencv路径下的一些文件进行拷贝。

E:\opencv3.4\opencv\build\x64\vc15\bin

上面的是我的opencv安装位置,然后将其下的

OpenCVFrameConverter 人脸识别 m3u8_opencv_04


这几个文件拷贝到需要训练的位置,注意里面的.dll文件不能忘记哦。至此,我们的准备工作已经齐全了。

接下来要做的就是进行分类训练了。

vec文件获取:

使用快捷键win+R输入cmd:

然后进入目标位置,也就是自己训练的位置。

OpenCVFrameConverter 人脸识别 m3u8_人工智能_05


然后使用opencv_createsamples.exe

OpenCVFrameConverter 人脸识别 m3u8_机器学习_06


这个是该应用程序的参数,只需要按照自己的需求进行调整即可。

opencv_createsam

plesd.exe -info E:\image\face\positive\info.dat -vec E:\image\face\sample_310.ve

c -num 760 -bgcolor 0 -bgthresh 0 -w 24 -h 24

最终会得到一个vec文件。
提示:这里可以添加要学的内容
例如:
1、 搭建 Java 开发环境
2、 掌握 Java 基本语法
3、 掌握条件语句
4、 掌握循环语句


开始训练:

opencv_traincascaded.exe -data E:\image\face -vec E:\image\face\sample_310.vec -bg bg.txt -numPos 500-numNeg 1500 -numStages 12 -featureType LBP -w 24 -h 24 -minHitRate 0.995 -maxFalseAlarmRate 0.5

OpenCVFrameConverter 人脸识别 m3u8_人工智能_07


这个是一些参数,可以根据自己的需要进行调整。

最终训练结束会得到一个xml文件,接下来我们就用用这个文件去做验证了。

ui->setupUi(this);
    VideoCapture capture(0);
//    capture.set(CAP_PROP_FRAME_WIDTH, 540.0);//设置摄像头采集图像分辨率
//    capture.set(CAP_PROP_FRAME_HEIGHT, 680.0);
    String fileName = "E://Trainslation//xml3//cascade.xml";
    //Mat img = imread("C:/Users/HS/Desktop/test.jpg");
    CascadeClassifier left_classifier;
    if (!left_classifier.load(fileName)) {
            printf("could not load face feature data...\n");
     }
     Mat Gary,outs;
     vector<Rect> left;
    //cvtColor(img,Gary,COLOR_BGR2GRAY);
    //equalizeHist(Gary,Gary);
//    left_classifier.detectMultiScale(Gary,left,1.1,3,0| cv::CASCADE_SCALE_IMAGE,Size(20,20));
//    for(size_t t= 0 ; t<left.size();t++)
//            {
//                rectangle(img,left[static_cast<int>(t)],Scalar(0,0,255),2,8,0);
//            }
//    imshow( "output",img);

    while(1)
    {
        Mat frame;
       capture>>frame;
       cvtColor(frame,Gary,COLOR_BGR2GRAY);
       equalizeHist(Gary,Gary);
       left_classifier.detectMultiScale(Gary,left,1.1,3,0,Size(40,40));
       waitKey(100);
       for(size_t t= 0 ; t<left.size();t++)
       {
           rectangle(frame,left[static_cast<int>(t)],Scalar(0,0,255),2,8,0);
       }
       imshow("The src imput img",frame);
        waitKey(40);
     }

结果验证:

OpenCVFrameConverter 人脸识别 m3u8_opencv_08


还是可以成果找到自己的,效果还是欠佳,多训练几次,加大训练量效果会更好的。

总结

通过一段时间对于opencv的学习,感觉opencv的应用还是很不错的,在于图像处理方面拥有这极好的应用。想起来之前动手做摄像头循迹小车的时候。当时用的是ov2640做的图像处理,里面要对每一帧图像的每一个像素点做一个判断,最终也就做出来一个黑白二值化的结果,如今应用opencv可以轻松做到这些个,自己学习的道路还是很长,也希望跟志同道合的朋友一起钻研项目,一起成长。