opencv5-objdetect之級聯分類器


這是《opencv2.4.9tutorial.pdf》的objdetect module的唯一一個例子。

在opencv中進行人臉或者人眼 或者身體的檢測 首先就是訓練好級聯分類器,然后就是檢測就行。在opencv中,“opencv/sources/data中就有內置訓練好的:基於haar特征的級聯分類器、基於hog特征的級聯分類器、基於lbp特征的級聯分類器”三種。相比較來說 算haar文件夾中的分類器最多,其他兩個比如:hog的只有一個行人檢測分類器“hogcascade_pedestrians.xml”而已;

  lbp的有三個分類器:“lbpcascade_frontalface.xml”、“lbpcascade_profileface.xml”、“lbpcascade_silverware.xml”。·

采用的是級聯分類器類:CascadeClassifier,並通過不同的分類器類型進行初始化。

1、先設定不同的分類器:

這里使用自帶的haar特征的前人臉和眼睛級聯分類器:

 string face_cascade_name = "haarcascade_frontalface_alt.xml";
     string eyes_cascade_name = "haarcascade_eye_tree_eyeglasses.xml";
2、然后進行分類器類的初始化:

CascadeClassifier face_cascade;
 CascadeClassifier eyes_cascade;
 if( !face_cascade.load( face_cascade_name ) ){ printf("--(!)Error loading\n"); return -1; };
   if( !eyes_cascade.load( eyes_cascade_name ) ){ printf("--(!)Error loading\n"); return -1; };
這里使用load()函數進行加載,當然也可以定義類的對象的時候進行初始化。load()函數的返回值是bool類型。

當不需要該分類器可以使用cvReleasehaarClassifierCascade(&cascade);進行釋放。

3、進行對象的檢測

void CascadeClassifier::detectMultiScale(const Mat& image, vector<Rect>& objects, double scaleFactor=1.1, int minNeighbors=3, int flags=0,
Size minSize=Size(), Size maxSize=Size())

這是這個函數的原型,是用來在輸入圖像中檢測不同尺寸的對象,檢測的對象將會作為一個矩形列表,也就是原型中的第二個參數。

參數列表:需要檢測的圖像(矩陣的類型為CV_8U)、矩形vector容器用來裝填所包含的檢測到的對象、在每個圖像尺度上需要進行縮放的因子、候選矩形框所需要包含的鄰居大小、已經廢棄的參數、可能的對象尺寸的最小值、可能的對象的尺寸的最大值;

最后兩個參數就是用來控制范圍的,使得能夠忽略小於最小的和大於最大的;第一個參數的要求是灰度圖像,所以不能是彩色,需要進行轉換:

vector<Rect> faces;
  Mat detFrame_gray;

  cvtColor( srcFrame, detFrame_gray, CV_BGR2GRAY );
  equalizeHist( detFrame_gray, detFrame_gray );
face_cascade.detectMultiScale( detFrame_gray, faces, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, Size(30, 30) );
上面就是會自動檢測人臉然后將檢測到的人臉的個數和每個人臉的矩形區域放在faces這個容器類中。上面最后一個最大值未指定大小,只設定了最小的對象矩形大小。

 for( int i = 0; i < faces.size(); i++ )
  {
    Point center( faces[i].x + faces[i].width*0.5, faces[i].y + faces[i].height*0.5 );
    ellipse( frame, center, Size( faces[i].width*0.5, faces[i].height*0.5), 0, 0, 360, Scalar( 255, 0, 255 ), 4, 8, 0 );

    Mat faceROI = frame_gray( faces[i] );
    vector<Rect> eyes;

    //-- 在每張人臉上檢測雙眼
    eyes_cascade.detectMultiScale( faceROI, eyes, 1.1, 2, 0 |CV_HAAR_SCALE_IMAGE, Size(30, 30) );

    for( int j = 0; j < eyes.size(); j++ )
     {
       Point center( faces[i].x + eyes[j].x + eyes[j].width*0.5, faces[i].y + eyes[j].y + eyes[j].height*0.5 );
       int radius = cvRound( (eyes[j].width + eyes[i].height)*0.25 );
       circle( frame, center, radius, Scalar( 255, 0, 0 ), 4, 8, 0 );
     }
  }
上面通過對每個人臉中,先定位好每個人臉的中心位置,然后在采用畫橢圓的方式來講人臉進行框出來,並且對每個框出來的位置進行選取ROI感興趣區域來檢測眼睛。並將檢測到的眼睛用圓框出來。

notes:不論是上面的人臉還是眼睛檢測,其中的第一個參數都是被檢測的圖像,而且在后面的畫橢圓和圓的過程中第一個參數仍然是原圖像,最后加個imshow()的函數就可以進行顯示檢測到的結果。

其中的cvRound()函數的原型為 int cvRound(double value);將參數轉化成與其最接近的整數。

下面這部分來自於http://blog.csdn.net/vsooda/article/details/7543789

但是也和《opencv2.4.9refman.pdf》的448頁一樣,相信該作者也是翻譯過來的。

目前人臉檢測分類器大都是基於haar特征利用Adaboost學習算法訓練的。

目標檢測方法最初由Paul Viola [Viola01]提出,並由Rainer Lienhart [Lienhart02]對這一方法進行了改善. 首先,利用樣本(大約幾百幅樣本圖片)的 harr 特征進行分類器訓練,得到一個級聯的boosted分類器。訓練樣本分為正例樣本和反例樣本,其中正例樣本是指待檢目標樣本(例如人臉或汽車等),反例樣本指其它任意圖片,所有的樣本圖片都被歸一化為同樣的尺寸大小(例如,20x20)。

分類器訓練完以后,就可以應用於輸入圖像中的感興趣區域(與訓練樣本相同的尺寸)的檢測。檢測到目標區域(汽車或人臉)分類器輸出為1,否則輸出為0。為了檢測整副圖像,可以在圖像中移動搜索窗口,檢測每一個位置來確定可能的目標。 為了搜索不同大小的目標物體,分類器被設計為可以進行尺寸改變,這樣比改變待檢圖像的尺寸大小更為有效。所以,為了在圖像中檢測未知大小的目標物體,掃描程序通常需要用不同比例大小的搜索窗口對圖片進行幾次掃描。

分類器中的“級聯”是指最終的分類器是由幾個簡單分類器級聯組成。在圖像檢測中,被檢窗口依次通過每一級分類器, 這樣在前面幾層的檢測中大部分的候選區域就被排除了,全部通過每一級分類器檢測的區域即為目標區域。 目前支持這種分類器的boosting技術有四種: Discrete Adaboost, Real Adaboost, Gentle Adaboost and Logitboost。"boosted" 即指級聯分類器的每一層都可以從中選取一個boosting算法(權重投票),並利用基礎分類器的自我訓練得到。基礎分類器是至少有兩個葉結點的決策樹分類器。 Haar特征是基礎分類器的輸入,主要描述如下。目前的算法主要利用下面的Harr特征。

個人:其實過程就是這樣,如果感興趣,更多的應該是使用自己訓練的分類器,在目標檢測這部分中,暫時只介紹了級聯分類器類,在《opencv2.4.9refman》中還介紹了潛在SVM分類器,不過還沒有對應的例子罷了。



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM