目标检测程序开发(三)——级联分类器训练

目标检测分为3个阶段

1.      样本创建

2.      训练分类器

3.      使用训练好的分类器进行目标检测

级联分类器

源地址http://www.opencv.org.cn/opencvdoc/2.3.2/html/modules/objdetect/doc/cascade_classification.html

基于Haar特征的用于目标检测的级联分类器

下面描述的目标检测器最初由PaulViola提出,由RainerLienhart改进,

论文分别是Paul Viola and Michael J.Jones. Rapid Object Detection using a Boosted Cascade of Simple Features. IEEECVPR, 2001. The paper is available online athttp://www.ai.mit.edu/people/viola/

RainerLienhart and Jochen Maydt. An Extended Set of Haar-like Features for RapidObject Detection. IEEE ICIP 2002, Vol. 1, pp. 900-903, Sep. 2002. This paper,as well as the extended technical report, can be retrieved athttp://www.lienhart.de/Publications/publications

首先,一个分类器(这里指的是使用类Haar特征的提升的分类器的级联)由几百个特定的目标(一张脸或一辆汽车)样本训练,这些目标称为正样本,缩放到了相同的大小(比如20x20),训练还需要负样本,相同大小的任意图片

一个分类器训练之后,它可以应用到输入图像的感兴趣的区域(和训练时使用的大小相同)。如果这个区域很可能显示了目标(脸或汽车),分类器输出1,否则输出0.为了在整个图像中搜索目标,可以在整个图片中移动搜索窗口并使用分类器检查每个窗口。考虑到我们感兴趣的目标可能大小不同,分类器被设计为可以很容易的调整大小,这比调整图片的大小要更高效。所以寻找一个未知大小的目标,扫描程序可能需要按照不同大小扫描多次。

分类器名字中的”级联“Cascade指的是最后的分类器包含几个简单的分类器(stage),这些stage依次应用到一个感兴趣的区域,直到某个stage下拒绝这个区域(stage检测为不是目标)或者全部的stage都通过了这个区域,就是说全都检测为目标。”提升“boosted的意思是级联分类器的每一个stage自身是复杂的,是使用某一种提升技巧组合基本的分类器构建而成,当前支持DiscreteAdaboost, Real Adaboost, Gentle Adaboost and
Logitboost 4种。基本分类器是至少有两个叶子的决策树。类Haar特征是基本分类器的输入。当前算法使用下列类Haar特征

一个特定的分类器使用的特征由它检测区域的形状,位置以及大小指定,由浅色区域累加值减去深色区域累加值计算,矩形区域的像素值之和可以用积分图快速计算。

新的C++接口也支持LBP特征。

样本创建和分类器训练

我刚刚发现级联分类器的训练有中文版的官方文档,,,

http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/user_guide/ug_traincascade.html

里面对于样本创建和级联分类器的训练描述很具体,里面的辅助工具在配置环境变量的时候已经用过一个,用来验证环境变量配置是否成功,使用的时候直接在命令行里使用即可。

下面是我的操作的记录

我检测的目标是戴眼镜的头部

我的目录结构如图所示,neg文件夹里存放负样本,pos文件夹里存放正样本,正样本是我手动从图片里截出来的,只包含正样本,但是大小不同,所以需要后面使用工具创建样本

①生成bg.txt文件:在0723目录下【新建】cmd.txt文件,写进cmd.exe,然后保存,把后缀名改为bat,双击运行cmd.bat,输入 dir /bneg > bg.txt,得到bg.txt文件

然后使用记事本的【替换】功能,把My全部替换为neg/My,将文件的每一行改为neg/MyPhoto2015_0721_190001.jpg的形式

②生成info.dat文件:根据官网文档,结合我的目录结构,info.dat的每一行应该是

pos/MyPhoto2015_0721_193020.jpg  1 0  0 167 251的形式,我的正样本已经手动裁剪过了,并且每个样本只含有一个数目,所以后面跟着 1 位置是 0 0,但是我的样本大小是不一样的,我的正样本大概有五百个,一个个手动添加太麻烦,我写了几行java程序GetInfo.java(附在本文最后),读取图片的宽高像素,直接写到info.dat文件,里面硬编码了路径,只有一个命令行参数,区分当前是哪个目录,区分是training下的0722目录还是0723目录,使用如下:

新建一个getinfo.bat文件,内容如下:0723就是指定目录

javac GetInfo.java

java GetInfo 0723

pause

双击运行后结果如下:

已经符合要求

③下一步就是创建样本

新建一个create_samples.bat文件,内容如下:

del p.vec

pause

opencv_createsamples  -info info.dat  -vec p.vec -w 50  -h 50  -show TRUE -num 580

pause

各个参数就是根据官方文档给出的含义设定的

双击运行后如下,可以看到已经生成的p.vec文件

④开始训练,还是创建一个start_traing.bat文件,用批处理文件的好处不用每次训练的时候都要手动敲一长串命令,可以简单修改后重复使用。内容如下:

opencv_traincascade   -data ./RESULT   -vec p.vec -bg bg.txt   -numPos 500   -numNeg 300   -numStages  5  ^

-stageType BOOST   -featureType HAAR -w50   -h 50  ^

-bt GAB  -minHitRate 0.995  -maxFalseAlarmRate  0.5  -weightTrimRate  0.95  -maxDepth 1   -maxWeakCount 1  ^

-mode ALL  > train.log

我把它的输出重定向到了train.log 文件里面

注意^后面不能有多余空格

最好手动创建RESULT文件夹,否则好像会出错,还有训练的参数很多,要理解每个参数的意义,填写正确,比如我当时急于开始训练,没有仔细阅读官方的文档,参数的设置在网上搜了一个就直接套用,程序抛出了一个异常,提示No sufficient samples,就是我的-numPos参数写的是500,当时我的正样本只有300多个,然后就又加了200个样本,然后发现其实是参数设置的问题,,,

我的笔记本内存只有4G,,,,还经常出现内存分配不了的异常,,,,

设置完毕后就可以开始训练了,双击start_traing.bat开始训练!

训练时间一般得几个小时吧,可以看看train.log看一看训练进度,,,

GetInfo.java代码

import java.awt.image.BufferedImage;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import javax.imageio.ImageIO;

public class GetInfo {

	public static void main(String[] args) {
		if(args.length<1){
			System.out.println("需要一个参数");
			System.out.println("比如 0722");
			System.out.println("生成到 E:\\training\\0722\\info.dat");
			return;
		}
		File info = new File("E:\\training\\"+args[0]+"\\info.dat");
		info.delete();
		if(!info.exists()){
			try {
				info.createNewFile();
			} catch (IOException e2) {
				e2.printStackTrace();
			}
		}
		FileWriter fileWritter=null;
		try {
			fileWritter = new FileWriter(info.getAbsolutePath(),true);
		} catch (IOException e1) {
			e1.printStackTrace();
		}
        BufferedWriter infoWritter = new BufferedWriter(fileWritter);

		String path = "E:\\training\\"+args[0]+"\\pos";
		File file = new File(path);
		File[] fileList = file.listFiles();

		BufferedImage bi = null;
		for(int i=0;i<fileList.length;i++){
			if(fileList[i].isFile()){

				try {
					bi = ImageIO.read(fileList[i]);
				} catch (IOException e) {
					e.printStackTrace();
				}
				int width = bi.getWidth();
				int height = bi.getHeight();
				try {
					infoWritter.write("pos/"+fileList[i].getName()+"  1  0  0 "+width+" "+height);
					infoWritter.newLine();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		try {
			infoWritter.flush();
			infoWritter.close();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-04 10:04:51

目标检测程序开发(三)——级联分类器训练的相关文章

目标检测程序开发(二)——Boosting算法简介

本文主要参考了OpenCV的官方文档 http://docs.opencv.org/modules/ml/doc/boosting.html boosting算法是一个监督式机器学习算法,它解决的是一个二元分类问题.本文包括对算法思想的理解,不包含算法的数学推导. 目标检测就是用这个分类算法,把只含有目标的图片作为一类,不含有目标的作为另一类,然后训练分类器,进行检测的时候,输入一张图片,用一个窗口扫描这个图片,对每个窗口应用分类器,返回是目标的类别时,就检测到了目标. 监督式机器学习目标是找到

目标检测程序开发(一)——OpenCV2.4.11环境配置

本文使用的环境 操作系统:windows_8.1_x64(本文对x86同样适用) 集成开发环境:visual_studio_ultimate_2013 OpenCV版本:opencv-2.4.11 第一步,下载并安装OpenCV 在OpenCV官网下载http://opencv.org/downloads.html ,我选择了版本VERSION 2.4.11,选择这个版本的windows平台版本,单击OpenCVfor Windows下载. 下载完成后,双击opencv-2.4.11.exe进行

目标检测程序开发(四)——目标检测

遇到了一个不错的<OpenCV入门教程>http://www.opencv.org.cn/forum.php?mod=viewthread&tid=33549 包含矩阵类的操作,以及其内存管理的介绍 以及读写图像和视频的操作. 一个例子 #include<iostream> #include"opencv2/opencv.hpp" using namespace std; using namespace cv; int main(){ CascadeCl

WPF触控程序开发(三)——类似IPhone相册的反弹效果

用过IPhone的都知道,IPhone相册里,当图片放大到一定程度后,手指一放,会自动缩回,移动图片超出边框后手指一放,图片也会自动缩回,整个过程非常和谐.自然.精确,那么WPF能否做到呢,答案是肯定的. 在没有现成的控件的情况下,只有自己做,你肯定想到做动画,WPF触屏开发提供了相应的功能来获取触控点的一些变化,这些变化的最佳消费者个人认为是Matrix.我们回想下做动画一般怎么做,比如给一个button做个宽度增5的动画,我们一般是定义一个DoubleAnimation,然后定义一个Sotr

机器学习-分类器-级联分类器训练(Train CascadeClassifier )

一.简介: adaboost分类器由级联分类器构成,"级联"是指最终的分类器是由几个简单分类器级联组成.在图像检测中,被检窗口依次通过每一级分类器,这样在前面几层的检测中大部分的候选区域就被排除了,全部通过每一级分类器检测的区域即为目标区域. 分类器训练完以后,就可以应用于输入图像中的感兴趣区域的检测.检测到目标区域输出为1,否则输出为0.为了检测整副图像,在图像中移动搜索窗口,检测每一个位置来确定可能的目标.为了搜索不同大小的目标物体,在图像中检测未知大小的目标物体,扫描过程中用不同

级联分类器训练-----OpenCV

关键词:级联分类器.opencv_traincascade 下面简述操作过程: 准备正负样本:neg.pos 正负样本路径生成:dir /a/b>path.txt //path:pos or neg 正样本训练集生成:opencv_createsamples.exe -info pos\pos.txt -vec pos\pos.vec -num 799 -w 24 -h 24  pause 样本训练:opencv_traincascade.exe -data data -vec pos/pos.

关于级联分类器训练过程中遇到的问题

最近在做级联分类器的训练,训练和识别过程中不断的遇到的问题,现在把想起来的问题记录下来,方便以后再遇见的时候可以方便查阅,如果有同样做此项目的朋友,欢迎交流! 训练时负样本的准备: 我们自己制作了一个工具,将训练和识别所需要的所有步骤集中在一起,而不需要一个.bat一个.bat的训练或者识别.但是我们的工具在负样本准备阶段,不管是训练还是识别,只要样本个数超过30000个就会提示“遇到不适当的参数”的提醒,我检查了内存分配,数组大小检查,及有可能的逻辑错误,仍然出现这个讨厌的东西.但是也不能不训

微信小程序开发(三)-----手动创建目录结构

***************************************************************** 需求: 1. 屏幕打印红色字体 你好 ; 2. 自定义全局应用对象的方法getString, 在index.js页面实现etString方法 ***************************************************************** 本文以这一个例子讲解如何手动创建项目目录结构, 步骤如下: 1. 填写项目名称和目录 注意:

Android企业级应用程序开发完整训练:精通Android商业级开发最佳实践的24堂课

从企业级商业实战的角度入手,24小时内通过23个动手实战案例,循序渐进的对Android商业级别的应用程序开发要点各个击破,依托于在多年的Android(6款完整的硬件产品和超过20款应用软件)开发和企业级培训经验(超过150期的次Android的企业内训和公开课),旨在在实务的基础之上帮助你完成任何复杂程序的高质量Android应用程序开发,让Android开发跟上想象的速度.最后,通过ActivityManagerService揭秘Android应用程序一切行为背后的核心根源,让你从此开发应