opencv人脸检测分类器训练小结
这两天在初学目标检测的算法及步骤,其中人脸检测作为最经典的算法,于是进行了重点研究。该算法最重要的是建立人脸检测分类器,因此我用了一天的时间来学习分类器的训练。这方面的资料很多,但是能按照一个资料运行出结果的确实没有找到,因此我总结了自己的训练经验。
目标检测分为三个步骤:
1、样本的创建
2、训练分类器
3、利用训练的分类器进行目标检测
第一步:样本的创建
◆ 样本分两种: 正样本与负样本(也有人翻译成:正例样本和反例样本),其中正样本是指待检目标样本(例如人脸,汽车,鼻子等),负样本指其它任意图片。
◆ 所有样本图片都应该有同一尺寸,如32 * 32,并放在相应文件目录下,
◆ 集合文件格式(collection file format)和描述文件格式(description file format)
集合文件格式(collection file format)就是如下形的描述文件:
[filename]
[filename]
[filename]
…
描述文件格式(description file format)就是如下形的描述文件:
[filename] [# of objects] [[x y width height] [... 2nd object] ...]
[filename] [# of objects] [[x y width height] [... 2nd object] ...]
[filename] [# of objects] [[x y width height] [... 2nd object] ...]
….
(x, y) 指左上角的坐标,width和 height 分别是样本的宽和高,这里我的图片是32*32的,所以两个值都是32
!!!!!!!负样本用集合文件格式描述,正样本用描述文件格式描述。
一、把所有正样本图片放在posdata的文件夹下,把所有负样本图片放在negdata文件夹下
(这里我以人脸图片样本为例)


(注:以上这些32*32 的图片均来自MIT人脸库,可以在csdn下载)
二. 分别为正样本和负样本创建描述文件
A. 为正样本创建描述文件格式文件info.txt,并且把这个文件放在与样本图片同一目录下,例如我的目录为C:/OpenCV2.1/bin/posdata
a) 在命令行下 输入以下命令: dir /b > info.txt

b) 打开info.txt, 选择编辑-》替换,把所有的bmp 换成 bmp 1 0 0 32 32
c) 删除info.txt最后一行的 “info.txt”
B. 为负样本创建集合文件格式文件bg.txt, 并且把这个文件放在与样本图片同一目录下,例如我的目录为I:/negdata
a) 在命令行下 输入以下命令: dir /b > bg.txt
b) 删除bg.txt最后一行的 “bg.txt”
三、创建样本
许多文章都说Opencv 自带有创建样本的exe 文件,但是我的目录下却没有,所以我只能自己生成createsamples.exe文件,首先在opencv解压文件夹里找到opencv->apps->haartraining中createsample.cpp文件,然后将该文件使用的所有.h和.cpp文件都加入到一个工程中,然后编译运行,在编译过程中会有各种错误,可根据错误提示进行相应的改正,其中最主要的是缺少"#include "stdafx.h“",其他的错误就是包含的文件添加不够导致的。 这里我创建10个sample:
将检测的正负样本文件和createsamples.exe文件放到同一根目录下,并在DOS命令下输入以下内容:
命令是: createsamples.exe -info info.txt -vec pos.vec -num 10 -w 20 -h 20
(关于 opencv_createsamples.exe 的参数用法,在参考英文资料网址http://note.sonots.com/SciSoftware/haartraining.html#e134e74e,里有详细介绍;
需要说明的是,我这里用的参数并没有 –bg, 因为根据那份文档,有了 –vec 和 –info 之后,就表示:Create training samples from some (从很多正样本中创建sample, 没有distortions)
四、训练分类器
如果在opencv的解压文件夹里没有找到haartraining.exe文件,则需要自己生成,其生成步骤与前一步createsamples.exe的生成步骤相同。
首先在根目录下建xml文件夹存放训练的分类器,并输入命令:
haartraining.exe -data xml-vec pos.vec -bg negdata0.txt -npos 10 -nneg 10 -mem 512 -model all -w 20 -h 20
这时会在根目录下的xml文件夹里生成许多.txt文件。
五、将生成的.txt文件制作成.xml文件
首先在opencv解压文件夹里找到opencv->samples->c->convert_cascade.c,将其加入到工程中,编译运行生成convert_cascade.exe文件,并将其放到原来的根目录下,在DOS命令下输入:
convert_cascade --size = "32x32" xml haarcascade.xml
则在根目录下生成该.xml文件。
五、利用生成的.xml分类器进行人脸检测
该代码如下,将lena.jpg放到工程文件夹下,由于本.xml只训练了10张照片,样本数少,所以检测效果很差,但是检测过程是正确且完整的。
#include "stdafx.h"
#include "cv.h"
#include "highgui.h" #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <math.h>
#include <float.h>
#include <limits.h>
#include <time.h>
#include <ctype.h> #ifdef _EiC
#define WIN32
#endif
IplImage* image;
IplImage* copyimage;
static CvMemStorage* storage = 0;
static CvHaarClassifierCascade* cascade = 0; void detect_and_draw( IplImage* image ); const char* cascade_name = "xml.xml"; int main( int argc, char** argv )
{
cascade = (CvHaarClassifierCascade*)cvLoad( cascade_name, 0, 0, 0 ); if( !cascade )
{
fprintf( stderr, "ERROR: Could not load classifier cascade\n" );
fprintf( stderr,
"Usage: facedetect --cascade=\"<cascade_path>\" [filename|camera_index]\n" );
return -1;
}
storage = cvCreateMemStorage(0); image = cvLoadImage("lena.jpg");
if( !image )return -1; cvNamedWindow("Original Image",1);
cvShowImage("Original Image",image); detect_and_draw( image ); cvWaitKey(0);
cvDestroyWindow("Original Image");
cvDestroyWindow("result"); return 0;
} void detect_and_draw( IplImage* img )
{
static CvScalar colors[] =
{
{{0,0,255}},
{{0,128,255}},
{{0,255,255}},
{{0,255,0}},
{{255,128,0}},
{{255,255,0}},
{{255,0,0}},
{{255,0,255}}
}; double scale = 1.3;
IplImage* gray = cvCreateImage( cvSize(img->width,img->height), 8, 1 );
IplImage* small_img = cvCreateImage( cvSize( cvRound (img->width/scale),
cvRound (img->height/scale)),
8, 1 );
int i; cvCvtColor( img, gray, CV_BGR2GRAY );
cvResize( gray, small_img, CV_INTER_LINEAR );
cvEqualizeHist( small_img, small_img );
cvClearMemStorage( storage ); if( cascade )
{
double t = (double)cvGetTickCount();
CvSeq* faces = cvHaarDetectObjects( small_img, cascade, storage,
1.1, 2, 0/*CV_HAAR_DO_CANNY_PRUNING*/,
cvSize(30, 30) );
t = (double)cvGetTickCount() - t;
printf( "detection time = %gms\n", t/((double)cvGetTickFrequency()*1000.) );
for( i = 0; i < (faces ? faces->total : 0); i++ )
{
CvRect* r = (CvRect*)cvGetSeqElem( faces, i );
CvPoint center;
int radius;
center.x = cvRound((r->x + r->width*0.5)*scale);
center.y = cvRound((r->y + r->height*0.5)*scale);
radius = cvRound((r->width + r->height)*0.25*scale);
cvCircle( img, center, radius, colors[i%8], 3, 8, 0 );
}
} cvShowImage( "result", img );
cvReleaseImage( &gray );
cvReleaseImage( &small_img );
}
opencv人脸检测分类器训练小结的更多相关文章
- 【计算机视觉】如何使用opencv自带工具训练人脸检测分类器
前言 使用opencv自带的分类器效果并不是很好,由此想要训练自己的分类器,正好opencv有自带的工具进行训练.本文就对此进行展开. 步骤 1.查找工具文件: 2.准备样本数据: 3.训练分类器: ...
- keras系列︱人脸表情分类与识别:opencv人脸检测+Keras情绪分类(四)
引自:http://blog.csdn.net/sinat_26917383/article/details/72885715 人脸识别热门,表情识别更加.但是表情识别很难,因为人脸的微表情很多,本节 ...
- 基于Haar特征的Adaboost级联人脸检测分类器
基于Haar特征的Adaboost级联人脸检测分类器基于Haar特征的Adaboost级联人脸检测分类器,简称haar分类器.通过这个算法的名字,我们可以看到这个算法其实包含了几个关键点:Haar特征 ...
- 照片美妆---基于Haar特征的Adaboost级联人脸检测分类器
原文:照片美妆---基于Haar特征的Adaboost级联人脸检测分类器 本文转载自张雨石http://blog.csdn.net/stdcoutzyx/article/details/3484223 ...
- OpenCV——人脸检测
OpenCV支持的目标检测的方法: 利用样本的Haar特征进行的分类器训练,得到的级联boosted分类器(Cascade Classification) 1.加载级联分类器 CascadeClass ...
- Android+openCV人脸检测2(静态图片)
前几篇文章中有提到对openCV环境配置,这里再重新梳理导入和使用openCV进行简单的人脸检测(包括使用级联分类器) 一 首先导入openCVLibrary320 二 设置gradle的sdk版本号 ...
- opencv人脸检测,旋转处理
年会签到,拍自己的大头照,有的人可能会拍成横向的,需要旋转,用人脸检测并修正它(图片). 1. 无脑检测步骤为: 1. opencv 读取图片,灰度转换 2. 使用CascadeClassifier( ...
- OpenCV人脸检测并把图片写成avi视频
读出某一个文件夹下“jpg”后缀的全部图片后,用的OpenCV自带的人脸检测检测图片中的人脸,调整图片的大小写成一个avi视频. 主要是要记录一下CvVideoWriter的用法和如何从文件夹中读取某 ...
- 人脸检测学习笔记(数据集-DLIB人脸检测原理-DLIB&OpenCV人脸检测方法及对比)
1.Easily Create High Quality Object Detectors with Deep Learning 2016/10/11 http://blog.dlib.net/201 ...
随机推荐
- 目标检测的图像特征提取之(三)Haar特征
1.Haar-like特征 Haar-like特征最早是由Papageorgiou等应用于人脸表示,Viola和Jones在此基础上,使用3种类型4种形式的特征. Haar特征分为三类:边缘特征.线性 ...
- Linux 线程模型的比较:LinuxThreads 和 NPTL
Linux 线程模型的比较:LinuxThreads 和 NPTL GNU_LIBPTHREAD_VERSION 宏 大部分现代 Linux 发行版都预装了 LinuxThreads 和 NPTL,因 ...
- C语言命名规则
一.程序风格: 1.严格采用阶梯层次组织程序代码: 各层次缩进的分格采用VC的缺省风格,即每层次缩进为4格,括号位于下一行. 要求相匹配的大括号在同一列,对 ...
- iOS开发--数组
1.sortedArrayUsingSelector (按Key值大小对NSDictionary排序) NSMutableArray *array = [NSMutableArray arrayWit ...
- renameTo()方法的用法
使用renameTo()方法,可以将文件data.txt从C:\JavaApp\IOTest1\目录移动到C:\目录,并改名为newdata.txt import java.io.File; //将文 ...
- SQL Server数据库多种方式查找重复记录
摘要:SQL Server是一个关系数据库管理系统,SQL Server数据库的应用是很多的,SQL Server数据库赢得了广大用户的青睐,本文将主要为大家介绍关于SQL Server数据库中查找重 ...
- shell编程基础(4)case 与 function
case case语句不用多说和c++里一样,用作选择,但是linux的case语句在语法上和c++还是有些不同的. ###########This is program test the Case# ...
- JSTL、EL、ONGL、Struts标签的区别与使用
一.JSTL 来源 我们使用JSP开发信息展现非常方便,也可嵌入java代码用来实现相关逻辑,但同样带来了很多问题: jsp维护难度增加 出事提示不明确,不容易提示 分工不明确等 解决上面的问题可以 ...
- java开发之匿名内部类,接口的使用
下面的例子是Java.JDK7学习笔记上的 打算开发多人联机程序,对每个联机客户端,都会建立Client对象封装相关信息 1.Client.java public class Client { pri ...
- uva 10453 - Make Palindrome(dp, 记录路径)
题目 题意: 给一个字符串 ,判断最少插入多少个字符 使字符串成为回文串, 并输出回文串. 思路:先用dp判断需要个数, 再递归输出路径. #include <iostream> #inc ...