OpenCV 臉部偵測自學(2)

來源:互聯網
上載者:User
在看了文檔[2,3]後開始對照著看OpenCV代碼,看得暈頭轉向啊。又搜了網上的一些文章,先針對自己的理解做筆記如下,日後好在此基礎上補充。OpenCV臉部偵測之資料結構:

所有的結構都代表一個級聯boosted Haar分類器。級聯有下面的等級結構:

Cascade:

Stage1:

Classifier11:

Feature11

Classifier12:

Feature12

...

Stage2:

Classifier21:

Feature21

...

...

關於特徵

typedef struct CvTHaarFeature//Haar-like 特徵

{

    char desc[CV_HAAR_FEATURE_DESC_MAX];// haar_x3等描述feature的形狀

    int  tilted;//0->up-rightfeature, 1->45 rotated feature 見。

    struct

    {

        CvRect r;

        float weight;

    } rect[CV_HAAR_FEATURE_MAX];//一個feature由2-3個長方形組成

} CvTHaarFeature;

 

typedef struct CvFastHaarFeature

{

    int tilted; //0->up-right feature, 1->45rotated feature 見。

    struct

    {

        int p0, p1, p2, p3;//把上面的Feature中的r的四個角點位置按照映像左上方開始算起第幾個(offset)。這樣方便後面等積分圖算出來後直接把p0,p1,p2,p3當做下標來取積分數值即可。

        float weight;

    } rect[CV_HAAR_FEATURE_MAX];

} CvFastHaarFeature;

 

typedef struct CvIntHaarFeatures

{

    CvSize winsize;

    int count;

    CvTHaarFeature* feature;

    CvFastHaarFeature* fastfeature;

} CvIntHaarFeatures;

 

/* Prepared for training samples */

typedef struct CvHaarTrainingData

{

    CvSize winsize;    /* training image size */

    int    maxnum;      /* maximumnumber of samples *///(2000+2000)

    CvMat  sum;         /* sumimages (each row represents image) *///(2000+2000) x (20x20)

    CvMat  tilted;      /* tilted sumimages (each row represents image) *///(2000+2000) x (20x20)

    CvMat  normfactor;  /* normalizationfactor */

    CvMat  cls;         /* classes.1.0 - object, 0.0 - background */// 1 x (2000+2000)

    CvMat  weights;     /* weights *///1 x (2000+2000)Adaboost訓練的時候需要的樣本權值

    CvMat* valcache;   /* precalculated feature values (CV_32FC1) */

    CvMat* idxcache;   /* presorted indices (CV_IDX_MAT_TYPE) */

} CvHaarTrainigData;

 

typedef struct CvUserdata

{

    CvHaarTrainingData* trainingData;

    CvIntHaarFeatures* haarFeatures;

} CvUserdata;

以上描述的結構體可總結如下[1].

關於分類器

typedef struct CvCARTHaarClassifier//基於Haar-like特徵的弱分類器

{

    CV_INT_HAAR_CLASSIFIER_FIELDS()

 

    int count;//這個弱分類器需要的Haar-like特徵數目,如果上傳調用時nsplits為1這個count值即為1,也就是說一般理解的弱分類器。

    int* compidx;//選擇出的這個弱分類器的Haar-like特徵的序號

    CvTHaarFeature* feature; //選擇出的這個弱分類器的Haar-like特徵

    CvFastHaarFeature* fastfeature; //選擇出的這個弱分類器的Haar-like特徵

    float* threshold; //選擇出的這個弱分類器的Haar-like特徵的threshold

    int* left;//跟CART樹有關,應該是Node的序號

    int* right; //跟CART樹有關,應該是Node的序號

    float* val;//跟上面的threshold比較後的output值,其實是code裡面的Curleft和curright

} CvCARTHaarClassifier;

 

typedef struct CvStageHaarClassifier//基於Haar-like特徵的強分類器

{

    CV_INT_HAAR_CLASSIFIER_FIELDS()

    int count;

    float threshold;//強分類器的threshold,大於此值的output為1,小於此值的output為0

    CvIntHaarClassifier** classifier;//被轉化為弱分類器CvCARTHaarClassifier,

} CvStageHaarClassifier;

 

typedef struct CvCascadeHaarClassifier//基於Haar-like特徵的級聯強分類器

{

    CV_INT_HAAR_CLASSIFIER_FIELDS()

    int count;

   CvIntHaarClassifier** classifier; //被轉化為強分類器CvStageHaarClassifier

} CvCascadeHaarClassifier;

 

/* internal weak classifier*/

typedef struct CvIntHaarClassifier

{//感覺像是c++裡的抽象類別的意思

    CV_INT_HAAR_CLASSIFIER_FIELDS()

} CvIntHaarClassifier;

 

那麼這裡為什麼要使用一個如此複雜的結構呢。大體來說有兩個好處:
1、 方便弱分類器之間的切換,當我們不選用CART而是其他的弱分類器結構的時候,就可以調用CvIntHaarClassifier時轉換成其他的指標
2、 這樣方便了Haar訓練的過程和Boost過程的銜接。

訓練部分的介面及流程圖

OpenCV 有cvCreateTreeCascadeClassifier和cvCreateCascadeClassifier兩種級聯分類器,目前先討論後者。

建立Cascade分類器:

void cvCreateCascadeClassifier(

const char* dirname,//工作目錄

const char* vecfilename,//正樣本的描述檔案,其中包含正樣本的數目,寬高,以及所有樣本映像資料

const char* bgfilename,//負樣本的描述檔案,只包含負樣本的路徑

int npos, //用於訓練的正樣本的數目

int nneg, //用於訓練的負樣本的數目

int nstages,//訓練多少層

int numprecalculated, //MB

int numsplits, //在一個弱分類器中用的feature數目,1->stump classifier; 2或更多 -> CARTclassifier

float minhitrate, //每一個stage在訓練的時候需要達到的最低hit rate

float maxfalsealarm,//每一個stage在訓練的時候允許達到的最高的false alarm rate

float weightfraction,//boosting演算法的一個參數

int mode, //BASIC-> only uprightfeatures; ALL->full set of upright and 45度features;

int symmetric,//對稱的話可以加快訓練進程

int equalweights,//enable equal weightsfor positives and negatives.

int winwidth, //width of training images

int winheight, //height of training images

int boosttype, //DAB->Discrete Ada Boost;RAB->Real Ada Boost; LB->Logic Boost; GAB->Gentle Adaboost

int stumperror,//跟DAB有關的一個參數

)

  

建立Gentle Adaboost強分類器:

建立弱分類器:(以stump為例)不是我做的,是[1]裡的,openCV裡的代碼順序跟這個稍有出入,但是基本一致。

 

Curleft和curright 即為跟threshold比較後的output

  

Reference

1. http://wenku.baidu.com/view/87fccf09581b6bd97f19ea12.html

2. "Empirical Analysis of Detection Cascades of Boosted Classifiers for Rapid Object Detection" , Rainer Lienhart, Alexander Kuranov, Vadim Pisarevsky,2002

3. “Rapid Object Detection using a Boosted Cascade of Simple Features”, Paul Viola, Michael Jones, 2001

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.