加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

haartraining生成.xml文件过程

发布时间:2020-12-16 00:28:03 所属栏目:百科 来源:网络整理
导读:转自http://www.cnblogs.com/tornadomeet/archive/2012/03/28/2420936.html 基础学习笔记之opencv(3):haartraining生成.xml文件过程 1.准备正负样本: 在上一讲http://www.cnblogs.com/tornadomeet/archive/2012/03/27/2420088.html中,我们已经收集到了训

转自http://www.cnblogs.com/tornadomeet/archive/2012/03/28/2420936.html

基础学习笔记之opencv(3):haartraining生成.xml文件过程

1.准备正负样本:

在上一讲http://www.cnblogs.com/tornadomeet/archive/2012/03/27/2420088.html中,我们已经收集到了训练所用的正样本。下面就开始收集负样本了,负样本要求是:不能包含人脸,且图片大小也不需要归一化到正样本尺寸,只需比正样本尺寸大或者相等即可。建议负样本用灰度图,加快训练速度,且负样本一定不能重复,要增大负样本的差异性。

这里我采用的负样本是用的是weizmann团队http://www.wisdom.weizmann.ac.il/~vision/Seg_Evaluation_DB/dl.html网站上的图像分割数据库,里面有灰色图和彩色图,这里当然选取灰度图了。

总共用了200幅图片,大小大约在300*200像素,截图如下所示:

可以看出这些200多张图片基本都没有人脸,所以说应该是可以的。

正负样本的图片准备好了,下面就开始制作正负样本的描述文件了。

首先建立好文件夹,把图片拷贝好,如下所示:

Pos_image中放入的是正样本,neg_image放入的是负样本,test_image放入的是测试样本。并将后面要用到的2个工具.exe文件也拷贝过来(在opencv的安装目录C:Program Filesopencv2.3.1buildcommonx86下)。

2.生成正负样本描述文件:

建立正样本的描述文件:

打开cmd窗口,进入上图所在pos_img文件夹内,可以看到此文件夹图片显示如下:

使用命令dir /b >pos_image.txt。如图所示

且用editplus打开该文件,删除最后一行,最后将名字归一化如下所示:

其中的pos_image/是相对路径名,后面紧接着的是文件名,1代表一个文件,0 0 24 24表示这个文件的2个顶点位置坐标。保存退出即ok!

负样本的描述文件类似,只是不需要考虑其大小位置。

也是进入neg_imgae后在cmd内使用命令dir /b >neg_image.txt,如图所示:

同样删除最后一行文字,且将文件相对路径加入如下所示:

至此,训练数据准备完备了。

3.创建vec文件:

在创建vec文件时,需要把pos_image.txt和neg_image.txt两个样本描述文件剪切到上一目录,如图所示:

然后利用opencv_createsamples.exe应用程序在该目录下使用如下cmd命令:

其中的-vec是指定后面输出vec文件的文件名,-info指定正样本描述文件,-bg指定负样本描述文件,-w和-h分别指正样本的宽和高,-num表示正样本的个数。执行完该命令后就会在当前目录下生产一个pos.vec文件了。

4.使用opencv_haartraining.exe文件进行训练

首先在当前目录下新建一个xml文件夹用于存放生成的.xml文件。

在当前目录使用cmd命令:

Opcnv_haartraining.exe –data xml –vec pos.vec –bg neg_image.txt –nsplits 1 –sym –w 24 –h 24 –mode all –mem 1280

截图如下:

其中-data为输出xml中间文件的位置,-sym表示训练的目标为垂直对称,-nsplits 1表示使用简单的stump classfier分类。-mem 1280 表示允许使用计算机的1280M内存,-mode all 表示使用haar特征集的种类既有垂直的,又有45度角旋转的。

因为数据量不是很多,不到半个钟头就训练好了。在当前目录下生产了一个xml.xml文件,将其重名名为face_test.xml。

5.实验结果:

利用上面训练出来的face_test.xml文件来检测下人脸,首先来一张比较正面的人脸图,用奥巴马的,检测结果如下:

为了看看是否不是特别正的,且有背景干扰的结果,用了lena的图,检测结果如下:

上面说明其效果还是不错的。其测试源码和前面的博客http://www.cnblogs.com/tornadomeet/archive/2012/03/22/2411318.html的代码类似,删减了人眼检测的代码而已,源码如下:

 1 // face_detect.cpp : 定义控制台应用程序的入口点。
 2 //
 3 #include "stdafx.h"
 4 
 5 #include opencv2/objdetect/objdetect.hpp 6 #include opencv2/highgui/highgui.hpp 7 #include opencv2/imgproc/imgproc.hpp 8 #include opencv2/ml/ml.hpp 9 
10 #include <iostream>
11 #include <stdio.h>
12 
13 using namespace std;
14 namespace cv;
15 
16 void detectAndDraw( Mat& img,17                    CascadeClassifier& cascade,128); line-height:1.5!important">18                    double scale);
19 
20 String cascadeName = ./face_test.xml";人脸的训练数据
21 
22 int main( int argc,255); line-height:1.5!important">const char** argv )
23 {
24     Mat image;
25     CascadeClassifier cascade,nestedCascade;创建级联分类器对象26     double scale = 1.3;
27     image = imread("obama_gray.bmp",1);28     image = imread(lena_gray.jpg",1);
29     namedWindow( result1 );opencv2.0以后用namedWindow函数会自动销毁窗口30 
31     if( !cascade.load( cascadeName ) )从指定的文件目录中加载级联分类器32     {
33          cerr << ERROR: Could not load classifier cascade" << endl;
34          return 0;
35     }
36 
37     if( !image.empty() )读取图片数据不能为空38     {
39         detectAndDraw( image,cascade,scale );
40         waitKey(0);
41     }
42 
43     44 }
45 
46 47                    CascadeClassifier& cascade,128); line-height:1.5!important">48                    double scale)
49 {
50     int i = 51     double t = 52     vector<Rect> faces;
53     static Scalar colors[] =  { CV_RGB(0,128); line-height:1.5!important">255),128); line-height:1.5!important">54         CV_RGB(128,128); line-height:1.5!important">55         CV_RGB(255,128); line-height:1.5!important">56         CV_RGB(0),128); line-height:1.5!important">57         CV_RGB(58         CV_RGB(59         CV_RGB(60         CV_RGB(255)} ;用不同的颜色表示不同的人脸61 
62     Mat gray,smallImg( cvRound (img.rows/scale),cvRound(img.cols/scale),CV_8UC1 );将图片缩小,加快检测速度63 
64     cvtColor( img,gray,CV_BGR2GRAY );因为用的是类haar特征,所以都是基于灰度图像的,这里要转换成灰度图像65     resize( gray,smallImg,smallImg.size(),INTER_LINEAR );将尺寸缩小到1/scale,用线性插值66     equalizeHist( smallImg,smallImg );直方图均衡67 
68     t = (double)cvGetTickCount();用来计算算法执行时间
69 70 检测人脸
71 detectMultiScale函数中smallImg表示的是要检测的输入图像为smallImg,faces表示检测到的人脸目标序列,1.1表示
72 每次图像尺寸减小的比例为1.1,2表示每一个候选矩形需要记录2个邻居,CV_HAAR_SCALE_IMAGE表示使用haar特征,Size(30,30)
73 为目标的最小最大尺寸74     cascade.detectMultiScale( smallImg,faces,128); line-height:1.5!important">75         1.1,128); line-height:1.5!important">2,128); line-height:1.5!important">0
76         |CV_HAAR_FIND_BIGGEST_OBJECT
77 |CV_HAAR_DO_ROUGH_SEARCH78         |CV_HAAR_SCALE_IMAGE
79,128); line-height:1.5!important">80         Size(30,128); line-height:1.5!important">30) );
81 
82     t = (double)cvGetTickCount() - t;相减为算法执行的时间83     printf( detection time = %g msndouble)cvGetTickFrequency()*1000.) );
84     for( vector<Rect>::const_iterator r = faces.begin(); r != faces.end(); r++,i++ )
85     {
86         Mat smallImgROI;
87         vector<Rect> nestedObjects;
88         Point center;
89         Scalar color = colors[i%8];
90         int radius;
91         center.x = cvRound((r->x + r->width*0.5)*scale);还原成原来的大小92         center.y = cvRound((r->y + r->height*0.5)*scale);
93         radius = cvRound((r->width + r->height)*0.25*scale);
94         circle( img,center,radius,color,128); line-height:1.5!important">3,128); line-height:1.5!important">8,128); line-height:1.5!important">0 );
95         smallImgROI = smallImg(*r);
96     }
97     cv::imshow( 98 }

6.参考文献:

1.http://hi.baidu.com/zdd007007/blog/item/b2e7f026eec9e23f8644f959.html的博客。

2.http://blog.csdn.net/guxj821/article/details/6341239网友周明才的博客。

作者:tornadomeet 出处:http://www.cnblogs.com/tornadomeet 欢迎转载或分享,但请务必声明文章出处。 (新浪微博:tornadomeet,欢迎交流!)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读