浅析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分類器就是一顆結點是強分類器的決策樹
畢竟水平有限,希望大家看了這篇文章能夠多多指正,也希望小白能從中學到一點東西。
大家一起分享,才能一起變得強大~
總結
以上是生活随笔為你收集整理的浅析haartraining方法进行人脸检测的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CNG 关于 Key 相关的操作
- 下一篇: 改进初学者的PID-介绍