浅析haartraining方法进行人脸检测

上个月用了两周的时间,学习了用于人脸检测的haartraining算法,今天打算做一总结

首先先为和我一样的初学者推荐几篇博客

http://blog.csdn.net/zouxy09/article/details/7922923真的很感谢写这篇文章的博主,讲解深入浅出。本文中的主要逻辑也都是由他的文章启发而来,有部分引用的内容,这里提前声明。

http://blog.sina.com.cn/s/blog_5f853eb10100sdgn.html 这篇文章是AdaBoost算法的代码实现,注释实在是详细!赞

http://www.cnblogs.com/tornadomeet/archive/2012/03/28/2420936.html 这篇文章非常明白的讲解了如何利用opencv提供的可执行文件一步步尝试进行人脸识别


开始进入正题

haartraining方法是基于Haar特征和AdaBoost算法以及级联思想的

那么首先,特征是什么?

假设在人脸检测时我们需要有这么一个子窗口在待检测的图片窗口中不断的移位滑动,子窗口每到一个位置,就会计算出该区域的特征,这个能够按照我们规定的方式计算出某个区域的特征值的子窗口就是特征

那么haar特征又是什么

haar特征是由Viola、Lienhart等人提出的,原理并没有不同,这里不多赘述

大家可以参考我之前总结的人脸识别尝试(二)——Haar特征  总结的还是挺用心的,希望大家多支持

 http://blog.csdn.net/u011583927/article/details/44782197

总之,一个Haar特征的数据结构应该包含以下内容: 

*haar特征模板类型

*是否有旋转

*矩阵位置及大小


知道了Haar特性是什么,我们来聊聊AdaBoost算法

AdaBoost是一种具有一般性的分类器提升算法,既然是提升,那么一定是从弱分类器到强分类器的一个过程


先说弱分类器是怎样产生的

在这之前,我先引出一个最差的分类器,暂且叫它“糟糕分类器”

对于一个待检测的图片,选出任意一种Haar特征,就可以计算得到一个特征值

如果我们定义一个阈值,那么将计算的特征值与这个阈值进行比较,就能做出一个最低级的决策



我将这整个的过程称为一个“糟糕分类器”(实际上并没有这个称呼,只是我个人这样理解)用下图表示




显然仅仅凭借这样粗糙的方式不可能判别一副图片是否为人脸,因为它的效果确实太糟糕了。我们应用多个这样的糟糕分类器进行级联,如下图所示



  一个弱分类器就是一个基本和上图类似的决策树,最基本的弱分类器只包含一个Haar-like特征,也就是它的决策树只有一层,被称为树桩(stump)。注意:这里这样的结构还不能称之为弱分类器,因为我们的阈值目前为止还是未知,也可以理解为随意选取的,这样当然不行。

  对于这样一个弱分类器(或者说是二叉决策树)最重要的就是如何决定每个结点判断的输出,要比较输入图片的特征值和弱分类器中阈值。也就是要寻找合适的分类器阈值,使该分类器对所有样本的判读误差最低。寻找最优阈值的过程也就是我们进行样本训练的过程,训练后二叉决策树就是一个弱分类器。

  那么如何寻找最优阈值呢?对于某一种特征,我们可以将输入样本(既有正样本又有负样本)分别计算对应的特征值并按升序排序成一个队列Seq。那么我们将阈值取遍队列中每一个特征值,对于每次循环,计算分错样本的加权平均和,并记录。遍历完成后分错样本的加权最小的那个位置对应的特征值就是最优阈值。然后我们要根据这次阈值的选取,将错分的样本适当的增加权重,选取另一个Haar特征,重复上面的过程。直至训练出要求的个数个“糟糕分类器”级联起来组成一个弱分类器。


  现在我们已经能够得到弱分类器了。它的数据结构如下:

typedef struct CvCARTHaarClassifier
{CV_INT_HAAR_CLASSIFIER_FIELDS()int count;int* compidx;CvTHaarFeature* feature;CvFastHaarFeature* fastfeature;float* threshold;int* left;int* right;float* val;
} CvCARTHaarClassifier;

  

  那么由以上讨论,假设我们由第一组样本已经训练出了一个弱分类器。显然我们可以找出这个分类器错分的样本出来,与一些新样本组成第二组样本,由这组样本训练出第二个弱分类器。重复这个过程,可以得到T个弱分类器。我们组合这T个弱分类器成为一个强分类器CvStageHaarClassifier。我们先这样理解,让这些最优弱分类器根据自己的地位进行表决(判别的正确率决定其地位),决定当前判断的子窗口是否为人脸。这样一个表决过程就代表了强分类器。然后我们可以训练多个强分类器,让他们强强联手。还是构造一颗二叉决策树,树的每个节点是一个强分类器


强分类器的数据结构如下:

/* internal stage classifier */
typedef struct CvStageHaarClassifier
{CV_INT_HAAR_CLASSIFIER_FIELDS()int count;float threshold;CvIntHaarClassifier** classifier;
} CvStageHaarClassifier;

强强联手后就得到的最终的分类器,最终的分类器就如下图一样进行判决得出结论


最终的Haar分类器为CvTreeCascadeClassifier,它代表一颗树,树中的每一个节点的核心功能就是一个强分类器,数据结构如下:

typedef struct CvTreeCascadeClassifier
{CV_INT_HAAR_CLASSIFIER_FIELDS()CvTreeCascadeNode* root;      /* root of the tree */CvTreeCascadeNode* root_eval; /* root node for the filtering */int next_idx;
} CvTreeCascadeClassifier;/* internal tree cascade classifier node */
typedef struct CvTreeCascadeNode
{CvStageHaarClassifier* stage;struct CvTreeCascadeNode* next;struct CvTreeCascadeNode* child;struct CvTreeCascadeNode* parent;struct CvTreeCascadeNode* next_same_level;struct CvTreeCascadeNode* child_eval;int idx;int leaf;
} CvTreeCascadeNode;

到这里,haartraining的主要思想就都说清楚了

最后,我们总结一下上面的内容得出这样的结论:

一组学习样本可以通过训练得到一个弱分类器。

弱分类器就是一颗决策树,决策树的每个结点存储的是一种haar特征和对应的最优阈值

多个弱分类器可以构成一个强分类器

Haar分类器就是一颗结点是强分类器的决策树


毕竟水平有限,希望大家看了这篇文章能够多多指正,也希望小白能从中学到一点东西。

大家一起分享,才能一起变得强大~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/499572.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

haartraining训练分类器方法cvCreateTreeCascadeClassifier()详解——人脸识别的尝试系列(四)

本文将介绍opencv_haartraining.exe中训练分类器的核心方法cvCreateTreeCascadeClassifier()中参数的具体含义,以及具体实现代码附加详细的注释。最后给出运行截图以作代码阅读的参考 我们还是从具体的例子出发,以一些实际的参数帮…

常用知识总结——模板Template

1. 模板的概念。 我们已经学过重载(Overloading),对重载函数而言,C的检查机制能通过函数参数的不同及所属类的不同。正确的调用重载函数。例如,为求两个数的最大值,我们定义MAX()函数需要对不同的数据类型分别定义不同重载(Overload)版本。 /…

opencv视频读写和视频等间隔采样

今天学习了opencv的HighGUI的内容 总结了两个视频读写demo以备以后进行视频处理和识别用 demo1 视频的读取和写入 按顺序读取视频的每一帧。对于读取的每一帧图像,显示在窗口中,然后转化为灰度图像输出到指定的文件中。 运行期间可以按ESC键退出。 还…

Socket通用TCP通信协议设计及实现(防止粘包,可移植,可靠)

Socket通用TCP通信协议设计及实现(防止粘包,可移植,可靠) 引文 我们接收Socket字节流数据一般都会定义一个数据包协议。我们每次开发一个软件的通信模块时,尽管具体的数据内容是不尽相同的,但是大体上的框…

浅谈 Adaboost 算法

注:本文全文引用自http://blog.csdn.net/carson2005/article/details/41444289 当然作者也是转载的,原文是http://blog.csdn.net/haidao2009/article/details/7514787 写的很好所以转载过来以便之后再次翻阅。 一 Boosting 算法的起源 boost 算法系列的起…

如何理解离散傅里叶变换(一)实数形式傅里叶变换

如何理解离散傅里叶变换(一) ——实数形式傅里叶变换 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 本文…

快速傅里叶变换(FFT)

快速傅里叶变换(FFT) ------------------------------------------------------------------------------------------------------------------- 作者:随煜而安 时间:2015/7/21 注:本文为作者原创文章&#xff0c…

风机桨叶故障诊断(一) 样本的获取

风机桨叶故障诊断(一) 样本的获取今天团队接了个新项目,做一个风机桨叶故障诊断系统。虽然马上就是准备考研的关键期了,可是一想到这是我学习了机器学习后遇到的第一个实际项目,我觉得参与进来,也帮导师分担…

风机桨叶故障诊断(二) 获取图像几何主方向

风机桨叶故障诊断(二) 获取图像几何主方向 昨天,我将视频资源按帧抽取并筛选得到了可以用来提取样本的图像库。今天还是进行项目的准备工作。当我们拿到一张图片,我们的软件要做的大致可以分为三个步骤:从原图中识别桨…

风机桨叶故障诊断(三) 识别桨叶——初步构建BP神经网络

风机桨叶故障诊断(三) 识别桨叶——初步构建BP神经网络 新的一天,希望有好的运气。今天开始着手系统的第一个模块,从一幅图像中寻找到桨叶所在的位置。第一直觉我们的识别任务属于难度比较大,干扰因素多的了&#xff…

风机桨叶故障诊断(五) 修改隐含层神经元个数的尝试

风机桨叶故障诊断(五) 修改隐含层神经元个数的尝试 我们已经为训练一个更为稳健的神经网络做好了样本的准备工作,那么我们开始下一步的工作吧! 我们已经有了样本集,目前我筛选出来了247个正样本,652个负样本…

风机桨叶故障诊断(六) 利用自编码器进行特征学习

风机桨叶故障诊断(六) 利用自编码器进行特征学习 在之前的工作中,我已经初步构建了三层的BP神经网络,并已经从样本集的选取,模型的选择(隐含层神经元个数),和输出层神经元阈值选择这…

风机桨叶故障诊断(七) 滑动窗与非极大值抑制NMS

风机桨叶故障诊断(七)滑动窗与非极大值一直NMS 到目前为止,我已经利用自编码神经网络提取特征后训练得到了BP神经网络(参见:点击打开链接),且在测试样本集上表现不错。下面我们就要应用到实际中…

Distinctive Image Features from Scale-Invariant Keypoints-SIFT算法译文

本文全篇转载自如下博客,感谢博主的无私分享 http://www.cnblogs.com/cuteshongshong/archive/2012/05/25/2506374.html ------------------------------------------------------------------------------------------------------ 从尺度不变的关键点选择可区分的…