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 Files\opencv2.3.1\build\common\x86下)。

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 using namespace cv;
15
16 void detectAndDraw( Mat& img,
17 CascadeClassifier& cascade,
18 double scale);
19
20 String cascadeName = "./face_test.xml";//人脸的训练数据
21
22 int main( int argc, 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( "result", 1 );//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 return 0;
44 }
45
46 void detectAndDraw( Mat& img,
47 CascadeClassifier& cascade,
48 double scale)
49 {
50 int i = 0;
51 double t = 0;
52 vector<Rect> faces;
53 const static Scalar colors[] = { CV_RGB(0,0,255),
54 CV_RGB(0,128,255),
55 CV_RGB(0,255,255),
56 CV_RGB(0,255,0),
57 CV_RGB(255,128,0),
58 CV_RGB(255,255,0),
59 CV_RGB(255,0,0),
60 CV_RGB(255,0,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(), 0, 0, 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,
75 1.1, 2, 0
76 //|CV_HAAR_FIND_BIGGEST_OBJECT
77 //|CV_HAAR_DO_ROUGH_SEARCH
78 |CV_HAAR_SCALE_IMAGE
79 ,
80 Size(30, 30) );
81
82 t = (double)cvGetTickCount() - t;//相减为算法执行的时间
83 printf( "detection time = %g ms\n", t/((double)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, 3, 8, 0 );
95 smallImgROI = smallImg(*r);
96 }
97 cv::imshow( "result", img );
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,欢迎交流!)
 
分类: OpenCV

基础学习笔记之opencv(3):haartraining生成.xml文件过程[转]的更多相关文章

  1. 基础学习笔记之opencv(6):实现将图片生成视频

    基础学习笔记之opencv(6):实现将图片生成视频 在做实验的过程中.难免会读视频中的图片用来处理,相反将处理好的图片又整理输出为一个视频文件也是非经常常使用的. 以下就来讲讲基于opencv的C+ ...

  2. 基础学习笔记之opencv(24):imwrite函数的使用

    http://www.cnblogs.com/tornadomeet/archive/2012/12/26/2834336.html 前言 OpenCV中保存图片的函数在c++版本中变成了imwrit ...

  3. Java&Xml教程(四)使用DOM方式生成XML文件

    在前面的教程中,我们学习了使用DOM解析方式读取和修改XML文件内容,今天我们来学习如何使用DOM解析机制生成XML文件. 下面是我们对要生成的XML文件的具体要求: 1.根节点元素为"Em ...

  4. 【Unity Shaders】学习笔记——SurfaceShader(八)生成立方图

    [Unity Shaders]学习笔记——SurfaceShader(八)生成立方图 转载请注明出处:http://www.cnblogs.com/-867259206/p/5630261.html ...

  5. 0003.5-20180422-自动化第四章-python基础学习笔记--脚本

    0003.5-20180422-自动化第四章-python基础学习笔记--脚本 1-shopping """ v = [ {"name": " ...

  6. C#RabbitMQ基础学习笔记

    RabbitMQ基础学习笔记(C#代码示例) 一.定义: MQ是MessageQueue,消息队列的简称(是流行的开源消息队列系统,利用erlang语言开发).MQ是一种应用程序对应用程序的通信方法. ...

  7. handlebars.js基础学习笔记

    最近在帮学校做个课程网站,就有人推荐用jquery+ajax+handlebars做网站前端,刚接触发现挺高大上的,于是就把一些基础学习笔记记录下来啦. 1.引用文件: jquery.js文件下载:h ...

  8. Oracle基础学习笔记

    Oracle基础学习笔记 最近找到一份实习工作,有点头疼的是,有阶段性考核,这...,实际想想看,大学期间只学过数据库原理,并没有针对某一数据库管理系统而系统的学习,这正好是一个机会,于是乎用了三天时 ...

  9. 尚学堂JAVA基础学习笔记

    目录 尚学堂JAVA基础学习笔记 写在前面 第1章 JAVA入门 第2章 数据类型和运算符 第3章 控制语句 第4章 Java面向对象基础 1. 面向对象基础 2. 面向对象的内存分析 3. 构造方法 ...

随机推荐

  1. Linux磁盘管理——MBR 与 GPT

    硬件设备在Linux中文件名 如今IDE 磁盘几乎被淘汰,市面上最常见的磁盘就是SATA和SAS.个人计算机主要是SATA.很多Linux发行版下都将IDE磁盘文件名也都被仿真成 /dev/sd[a- ...

  2. 2. premiere 项目管理

    1.premiere 项目管理 可以对项目素材进行一个管理,方便我们对项目文件的编辑 1.序列选择,管理前更改好名称 2.管理保留原始素材,不要选择转码 3.通过浏览,选择存储路径 点击“计算”,显示 ...

  3. Java获取各种路径

    (1).request.getRealPath("/");//不推荐使用获取工程的根路径(2).request.getRealPath(request.getRequestURI( ...

  4. 开发一个代码的自动生成器,使用Jfinal4.3+Swagger+Sql

    -- 所有表名select column_name 列名, data_type 字段类型, column_comment 字段注释  from information_schema.columns  ...

  5. MVC模式:action、dao、model、service、util

    这就是一个典型的MVC: action:主要是Struts2,用来做跳转,比如jsp页面提交的表单就是进入到action里面,然后action再调用service里面的逻辑,最后返回到jsp响应请求. ...

  6. JOIN序列化过程中日期的处理

    一.在后台进行处理: System.Web.Script.Serialization.JavaScriptSerializer js = new System.Web.Script.Serializa ...

  7. Mac下安装SQLmap的安装

    1.cd /usr/bin/ 2.sudo git clone https://github.com/sqlmapproject/sqlmap.git sqlmap-dev3.重新打开terminal ...

  8. HDFS节点及原理

    HDFS节点角色: (1)namenode:1.用来存储HDFS的元数据信息,这里的元数据信息指的是文件系统的命名空间.启动时,将这些信息加载到namenode内存. 2.元数据信息也会在磁盘上保存成 ...

  9. 2019-2020-1 20199302《Linux内核原理与分析》第五周作业

    一.用户态.内核态和中断 1.一般现代cpu都有几种不用的指令执行级别 2.在高执行级别下,代码可以执行特权指令,访问任意的物理地址,这种CPU执行级别就对应着内核态. 3.在相应的低级别执行状态下, ...

  10. SaltStack 在 Windows 上的操作基础

    SaltStack 在 windows上的操作基础 1.删除文件: salt '172.16.3.11' file.remove 'D:\downup\111.msu' 2.删除文件夹 salt '1 ...