2001 Rapid object detection using a boosted cascade of simple features(Paul Viola et al)读后感

本文主要是介绍2001 Rapid object detection using a boosted cascade of simple features(Paul Viola et al)读后感,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、理论

      这篇文章主要有三个贡献:
1、类Harr特征和积分图
2、Adaboost
3、Cascade
同时,我还关注了训练和检测的流程,以及opencv中的实现

二、类Harr特征及数量

    下面是引用一篇文章。注意其中的Harr特征可以宽高放缩的。比如2*2的,计算数量的时候也需要包含2*4,2*6,参看图9

三、Adaboost

可以参考http://blog.csdn.net/dark_scope/article/details/14103983;http://blog.csdn.net/haidao2009/article/details/7514787;

在了解Adaboost方法之前,先了解一下Boosting方法。

回答一个是与否的问题,随机猜测可以获得50%的正确率。如果一种方法能获得比随机猜测稍微高一点的正确率,则就可以称该得到这个方法的过程为弱学习;如果一个方法可以显著提高猜测的正确率,则称获取该方法的过程为强学习1994年,KearnsValiant证明,在ValiantPACProbably ApproximatelyCorrect)模型中,只要数据足够多,就可以将弱学习算法通过集成的方式提高到任意精度。实际上,1990年,SChapire就首先构造出一种多项式级的算法,将弱学习算法提升为强学习算法,就是最初的Boosting算法。Boosting意思为提升、加强,现在一般指将弱学习提升为强学习的一类算法。1993年,DruckerSchapire首次以神经网络作为弱学习器,利用Boosting算法解决实际问题。前面指出,将弱学习算法通过集成的方式提高到任意精度,是KearnsValiant1994年才证明的,虽然Boosting方法在1990年已经提出,但它的真正成熟,也是在1994年之后才开始的。1995年,Freund和Schapire提出了Adaboost算法,是对Boosting算法的一大提升。Adaboost是Boosting家族的代表算法之一,全称为Adaptive Boosting。Adaptively,即适应地,该方法根据弱学习的结果反馈适应地调整假设的错误率,所以Adaboost不需要预先知道假设的错误率下限。也正因为如此,它不需要任何关于弱学习器性能的先验知识,而且和Boosting算法具有同样的效率,所以在提出之后得到了广泛的应用。



四、Cascade

级联分类器介绍:级联分类器就是将多个强分类器连接在一起进行操作。每一个强分类器都由若干个弱分类器加权组成,例如,有些强分类器可能包含10个弱分类器,有些则包含20个弱分类器,一般情况下一个级联用的强分类器包含20个左右的弱分类器,然后在将10个强分类器级联起来,就构成了一个级联强分类器,这个级联强分类器中总共包括200若分类器。因为每一个强分类器对负样本的判别准确度非常高,所以一旦发现检测到的目标位负样本,就不在继续调用下面的强分类器,减少了很多的检测时间。因为一幅图像中待检测的区域很多都是负样本,这样由级联分类器在分类器的初期就抛弃了很多负样本的复杂检测,所以级联分类器的速度是非常快的;只有正样本才会送到下一个强分类器进行再次检验,这样就保证了最后输出的正样本的伪正(false positive)的可能性非常低。 

也有一些情况下不适用级联分类器,就简单的使用一个强分类器的情况,这种情况下一般强分类器都包含200个左右的弱分类器可以达到最佳效果。不过级联分类器的效果和单独的一个强分类器差不多,但是速度上却有很大的提升。

级联结构分类器由多个弱分类器组成,每一级都比前一级复杂。每个分类器可以让几乎所有的正例通过,同时滤除大部分负例。这样每一级的待检测正例就比前一级少,排除了大量的非检测目标,可大大提高检测速度。

五、opencv编程

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

1、vec和info数据格式

vec格式:二进制文件(opencv_createsamples 能够生成能被 opencv_haartraining 和 opencv_traincascade 程序支持的正样本数据。它的输出为以 *.vec 为扩展名的文件,该文件以二进制方式存储图像。
count 包含的图像个数(每个图像仅包括纯数据)
size    图像的宽*高
max size的最大值
min size的最小值
数据 按每个图像顺序存储(以行为单位)

info格式
file 文件
count 上述文件中矩形框的个数
x1 y1 x2 y2      矩形的坐标

2、创建样本(opencv_createsamples

-info                       输入正样本描述文件,默认NULL

-img                       输入图像文件名,默认NULL

-bg                  负样本描述文件,文件中包含一系列的被随机选作物体背景的图像文件名,默认NULL

-num                  生成正样本的数目,默认1000

-bgcolor              背景颜色,表示透明颜色,默认0

-bgthresh         颜色容差,所有处于bgcolor-bgthresh和bgcolor+bgthresh之间的像素被置为透明像素,也就是将白噪声加到前景图像上,默认80

-inv                  前景图像颜色翻转标志,如果指定颜色翻转,默认0(不翻转)

-randinv              如果指定颜色将随机翻转,默认0

-maxidev             前景图像中像素的亮度梯度最大值,默认40

-maxxangle           X轴最大旋转角度,以弧度为单位,默认1.1

-maxyangle           Y轴最大旋转角度,以弧度为单位,默认1.1

-maxzangle           Z轴最大旋转角度,以弧度为单位,默认0.5

                                                         输入图像沿着三个轴进行旋转,旋转角度由上述3个值限定。

-show               如果指定,每个样本都将被显示,按下Esc键,程序将继续创建样本而不在显示,默认为0(不显示)

-scale                显示图像的缩放比例,默认4.0

-w                  输出样本宽度,默认24

-h                   输出样本高度,默认24

-vec                输出用于训练的.vec文件,默认NULL


(1)如果设置-img和-vec

调用cvCreateTrainingSamples,采用一张图像创建训练样本

(2)如果设置-img、-bg和-info

调用cvCreateTestSamples,采用一张图像创建测试样本。-bg在这里又有什么作用?目的是作为背景创建测试图像。

(3)如果设置-info和-vec(采用正样本描述文件中的图像创建训练样本)

调用cvCreateTrainingSamplesFromInfo,在cvCreateTrainingSamplesFromInfo中将读取样本,并resize后调用icvWriteVecHeader和icvWriteVecSample创建vec文件。

(4)如果只设置-vec(只显示vec文件中的样本)

调用cvShowVecSamples查看和检查保存在vec文件中正样本

3、训练(opencv_traincascade

使用train.dat调用%Opencv%\vs2008\bin\Release\ opencv_traincascade.exe

在traincascade.cpp中查阅参数设置

1基本参数

-data                            目录名,存放训练好的分类器,如果不存在训练程序自行创建

-vec                                  正样本.vec文件,由opencv_createsamples生成

-bg                            负样本描述文件

-numPos                      每级分类器训练时所用到的正样本数目

-numNeg                        每级分类器训练时所用到的负样本数目,可以大于-bg指定的图片数目

 -numStages                  训练分类器的级数

 -precalcValBufSize           缓存大小,用于存储预先计算的特征值,单位MB

-precalcIdxBufSize            缓存大小,用于存储预先计算的特征索引,单位M币

-baseFormatSave                 仅在使用Haar特征时有效,如果指定,级联分类器将以老格式存储

2级联参数cascadeParams

-stageType                    级联类型,staticconst char* stageTypes[] = { CC_BOOST };

-featureType                     特征类型,staticconst char* featureTypes[] = { CC_HAAR, CC_LBP, CC_HOG };

-w             

-h                                训练样本的尺寸,必须跟使用opencv_createsamples创建的训练样本尺寸保持一致

3Boosted分类器参数stageParams

-bt                      Boosted分类器类型

DAB-discrete Adaboost, RAB-RealAdaboost, LB-LogiBoost, GAB-Gentle Adaboost

-minHitRate                      分类器的每一级希望得到的最小检测率,总的最大检测率大约为

min_hit_rate^number_of_stages

-maxFalseAlarmRate           分类器的每一级希望得到的最大误检率,总的误检率大约为

                                                        max_false_rate^number_of_stages

-weightTrimRate               Specifies whether trimming should beused and its weight. 一个还不错的数值是0.95

-maxDepth                   弱分类器的最大深度,一个不错数值是1,二叉树

-maxWeightCount             每一级中弱分类器的最大数目

4Haar特征参数featureParams

-mode                          训练过程使用的Haar特征类型,CORE-Allupright  ALL-All Features BASIC-Viola

上述参数设置好后调用CvCascadeClassifier::train进行训练

将上述内容在train.dat中编辑好,运行即可。训练最终生成一个-data指定级联分类器的文件夹和一个cascade.xml文件,其余文件都是中间结果,当训练程序被中断之后,再重新运行训练程序将读入之前的训练结果,无需从头重新训练,训练结束后可以删除这些文件。

在cascade.xml文件中主要有stageType,featureType,width,height,stageParams,featureParams,stageNum,stages和features节点。 

stages中的stage数目是自己设定的,每个stage又包含多个weakClassifiers,每个weakClassifier又包含一个internalNodes和一个leafValues。internalNodes中四个变量代表一个node,分别为node中的left/right标记,特征池中的ID和threshold。leafValues中两个变量代表一个node,分别为leftleaf和right leaf值。

features是分类器的特征池,每个Haar特征包含一个矩形rect和要提取的特征序号,每个Hog特征/LBP特征包含一个矩形。


1 包含负样本的图像一定不小于在create中设置的尺寸

负样本图像可以是不同的尺寸,但是图像尺寸应该比训练窗口的尺寸大,在使用负样本图像时,OpenCV自动从负样本图像中抠出一块和正样本同样大小的区域作为负样本。具体可查阅icvGetNextFromBackgroundData,具体抠图过程为:
1)  确定抠图区域的左上角坐标(Point.x, Point.y)
2)  确定一个最小缩放比例,使得原负样本图像缩放后恰好包含选中负样本区域
3)  对原负样本图象按计算好的缩放比例进行缩放
4)  在缩放后的图像上抠出负样本。

2 –numPos一般比实际正样本数量少200-300,-numNeg是否存在同样的情况?正负样本选择规则?

如果出现:训练停留在一个分类器长达几小时没有相应,问题出现在取负样本的那个函数 icvGetHaarTrainingDataFromBG中;只有当之前的强分类器对负样本集内的样本全部分类正确时才会出现死循环,因为只要有一个样本会被错分为正样本,那么通过count次扫描整个负样本集就能得到count个负样本,当然这count个负样本实际上就是一个负样本的count个拷贝。为避免这种情况,负样本集中的样本数需要足够多 。

不过此时的分类器已经完全额、可以使用,因为它的误检率已经很低,从实用性上时没有任何问题的。所以我们可以通过设置-nstages 这个参数来限制分类器级数,适当时候停止并生成xml文件。

CvCascadeBoost::train中去查阅

函数                poscount= icvGetHaarTrainingDataFromVec( training_data, 0, npos,
                    (CvIntHaarClassifier*)tcc, vecfilename, &consumed )负责从正样本集*.vec 文件中载入 count(npos)个正样本。在程序第一次运行到此(即训练第一个分类器之前)时,只要正样本集中有 count 个样本,就一定能取出 count 个正样本。在以后运行到此时,有可能取不到 count 个样本,因为
必须是用前面的级联强分类器((CvIntHaarClassifier*) tcc)分类为正样本(即分类正确的样本)的样本才会被取出作为下一个强分类器训练样本,具体可参考 icvGetHaarTrainingData和icvEvalTreeCascadeClassifierFilter函数。

 

训练负样本,具体可参考icvGetHaarTrainingDataFromBG和icvEvalTreeCascadeClassifierFilter函数。

int icvGetHaarTrainingDataFromBG(CvHaarTrainingData* data, int first, int count,
                                  CvIntHaarClassifier*cascade, double* acceptance_ratio, const char * filename = NULL )
  传递返回值的 acceptance_ratio 参数记录的是实际取出的负样本数与查询过的负样本数(如果通过前面级联stage强分类器的负样本数很少时,那么程序会循环重复读取负样本,并用thread_consumed_count计数)之比(acceptance_ratio = ((double) count) / consumed_count),也就是虚警率,用于判断已训练的级联分类器是否达到指标,若达到指标,则停止训练过程。 

 
  注意函数 icvGetHaarTrainingData中一个主要的 For 循环:
        for( i = first; i < first +count; i++ ) //共读取 count 个负样本,当读取不到
        {                            //这么多负样本时将出现死循环!
 
  对上面代码中的注释有必要进一步说明一下:只有当之前的强分类器对负样本集内的样本全部分类正确时才会出现死循环。因为只要有一个样本会被错分为正样本,那么通过 count次扫描整个负样本集就能得到 count 个负样本,当然这 count 个负样本实际上就是一个负样本的 count 个拷贝。为避免这些情况的发生,负样本集中的样本数需要足够多。
  在负样本图像大小与正样本大小完全一致时,假设最终的分类器虚警率要求是falsealarm,参加训练的负样本要求是 count 个,则需要的负样本总数可计算如下: TotalCount = count / falsealarm
  以 Rainer Lienhart 的文章中的一些参数为例,falsealarm=0.5^20=9.6e-07, count=3000,
则 TotalCount=3000/(0.5^20)= 3,145,728,000=31 亿。

函数 icvGetHaarTrainingDataFromBG ()负责从负样本集中载入 count 个负样本。在程序第一次运行到此(即训练第一个分类器之前)时,只要负样本集中有 count 个样本,就一定能取出 count 个负样本。在以后运行到此时,有可能取不到 count 个样本,因为必须是用前面的级联强分类器分类为正样本的样本(即分类错误的样本)才会被取出作为下一个强分类器的负样本输入。
 

对于int icvGetHaarTrainingData( CvHaarTrainingData* data,int first, int count,
                            CvIntHaarClassifier*cascade,
                            CvGetHaarTrainingDataCallbackcallback, void* userdata,
                            int*consumed, double* acceptance_ratio )

 这个函数的解释:

这是个对于读取正负样本通用的函数,区别在于callback的调用。在这个函数中有个变量thread_getcount,表示将样本分为正样本的数目(不论这个样本是负样本还是正样本)。
  传递返回值的 Consumed 参数表示为取 count 个正样本,查询过的正样本总数。对于负样本为空(null),没有返回值。 

 

3 之前遇到过10*20的不能训练Hog特征的分类器?Hog特征是否存在尺寸限制?

         查阅Hog特征的计算方法,OpencvHogDescriptor









这篇关于2001 Rapid object detection using a boosted cascade of simple features(Paul Viola et al)读后感的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/622232

相关文章

uva 10014 Simple calculations(数学推导)

直接按照题意来推导最后的结果就行了。 开始的时候只做到了第一个推导,第二次没有继续下去。 代码: #include<stdio.h>int main(){int T, n, i;double a, aa, sum, temp, ans;scanf("%d", &T);while(T--){scanf("%d", &n);scanf("%lf", &first);scanf

【Python报错已解决】AttributeError: ‘list‘ object has no attribute ‘text‘

🎬 鸽芷咕:个人主页  🔥 个人专栏: 《C++干货基地》《粉丝福利》 ⛺️生活的理想,就是为了理想的生活! 文章目录 前言一、问题描述1.1 报错示例1.2 报错分析1.3 解决思路 二、解决方法2.1 方法一:检查属性名2.2 步骤二:访问列表元素的属性 三、其他解决方法四、总结 前言 在Python编程中,属性错误(At

时间序列|change point detection

change point detection 被称为变点检测,其基本定义是在一个序列或过程中,当某个统计特性(分布类型、分布参数)在某时间点受系统性因素而非偶然因素影响发生变化,我们就称该时间点为变点。变点识别即利用统计量或统计方法或机器学习方法将该变点位置估计出来。 Change Point Detection的类型 online 指连续观察某一随机过程,监测到变点时停止检验,不运用到

error while loading shared libraries: libnuma.so.1: cannot open shared object file:

腾讯云CentOS,安装Mysql时: 1.yum remove libnuma.so.1 2.yum install numactl.x86_64

java基础总结12-面向对象8(Object类)

1 Object类介绍 Object类在JAVA里面是一个比较特殊的类,JAVA只支持单继承,子类只能从一个父类来继承,如果父类又是从另外一个父类继承过来,那他也只能有一个父类,父类再有父类,那也只能有一个,JAVA为了组织这个类组织得比较方便,它提供了一个最根上的类,相当于所有的类都是从这个类继承,这个类就叫Object。所以Object类是所有JAVA类的根基类,是所有JAVA类的老祖宗

POJ 2001 Shortest Prefixes(字典树入门)

题目: http://poj.org/problem?id=2001 题意: 找到多个字符串中,各自唯一的最短子串,例如 carte 与 carce 各自唯一的最短子串为cart与carc,即不会与其它字符串的子串重复。 思路: 字典树 解题心得: 更新关键值的时机很重要 代码: #include<stdio.h>#include<string>typedef str

MACS bdgdiff: Differential peak detection based on paired four bedGraph files.

参考原文地址:[http://manpages.ubuntu.com/manpages/xenial/man1/macs2_bdgdiff.1.html](http://manpages.ubuntu.com/manpages/xenial/man1/macs2_bdgdiff.1.html) 文章目录 一、MACS bdgdiff 简介DESCRIPTION 二、用法

王立平--Object-c

object-c通常写作objective-c或者obj-c,是根据C语言所衍生出来的语言,继承了C语言的特性,是扩充C的面向对象编程语言。它主要使用于MacOSX和GNUstep这两个使用OpenStep标准的系统,而在NeXTSTEP和OpenStep中它更是基本语言。Objective-C可以在gcc运作的系统写和编译,因为gcc含Objective-C的编译器。在MA

使用django-simple-captcha遇到的坑

使用django-simple-captcha遇到的坑 一站点gongshare.com在做注册功能时验证码采用的django-simple-captcha,因为笔者开发环境采用的Windows 64bit系统,结果安装使用的时候接二连三遇到好几个坑。 django-simple-captcha需要依赖django1.3+、PIL1.1.7+或者Pillow2.0+,根据文档安装后开始使用时,

HYPERCASUAL - Simple Characters(卡通游戏火柴人物模型)

介绍HyperCasual - 简单角色! 一套低多边形角色资源,用于创建超休闲风格的游戏。 包含演示场景 角色(x10) 生化人、小丑、Flaty_Boss、女孩、守门员、英雄、亚马逊女战士、男人、红衣男人、修理工 每个网格大约有700-2000个顶点 角色设置与Mecanim兼容(本包中不包含动画) 着色器适用于可编写脚本的渲染管线(HD + LW) 下载:​​Unity资源商店链接资源