http://www.cnblogs.com/easymind223/archive/2012/07/03/2574826.htmlhtml
OpenCV自帶的adaboost程序可以根據用戶輸入的正樣本集與負樣本集訓練分類器,經常使用於人臉檢測,行人檢測等。它的默認特徵採用了Haar,不支持其它特徵。c++
Adaboost的原理簡述:(原文)
git
每一個Haar特徵對應看一個弱分類器,但並非任伺一個Haar特徵都能較好的描述人臉灰度分佈的某一特色,如何從大量的Haar特徵中挑選出最優的Haar特徵並製做成分類器用於人臉檢測,這是AdaBoost算法訓練過程所要解決的關鍵問題。算法
Paul Viola和Michael Jones於2001年將Adaboost算法應用於人臉檢測中,其基本思想是針對不一樣的訓練集訓練同一個分類器(弱分類器),而後把這些不一樣訓練集上的獲得的分類器聯合起來,構成一個最終的強分類器。Adaboost 算法中不一樣的訓練集是經過調整每一個樣本對應的權重來實現的。開始時,每一個樣本對應的權重是相同的,對於h1 分類錯誤的樣本,加大其對應的權重; 而對於分類正確的樣本, 下降其權重, 這樣分錯的樣本就被突出出來,從而獲得一個新的樣本分佈 U2 。在新的樣本分佈下,再次對弱分類器進行訓練,獲得弱分類器 h2 。依次類推,通過 T 次循環,獲得 T 個弱分類器,把這 T 個弱分類器按必定的權重疊加(boost)起來,獲得最終想要的強分類器。網絡
訓練系統整體框架,由「 訓練部分」和 「 補充部分」構成。依據系統框架,本文的訓練系統可分爲如下幾個模塊:
(1)以樣本集爲輸入,在給定的矩形特徵原型下,計算並得到矩形特徵集;
(2)以特徵集爲輸入,根據給定的弱學習算法,肯定閩值,將特徵與弱分類器一一對應,得到弱分類器集;
(3)以弱分類器集爲輸入, 在訓練檢出率和誤判率限制下, 使用A d a B o o s t 算法
挑選最優的弱分類器構成強分類器;
(4)以強分類器集爲輸入,將其組合爲級聯分類器;
(5)以非人臉圖片集爲輸入,組合強分類器爲臨時的級聯分類器,篩選並補充
非人臉樣本。app
訓練樣本的選擇:
訓練樣本要求是面部特寫圖像,圖1是一簇訓練樣本,大小被歸一化爲24×24像素,其中正訓練樣本要求是面部特寫圖像,可是人臉形態千差萬別,因此訓練樣本選取過程當中要考慮到樣本的多樣性。負訓練樣本,大小被歸一化爲24×24像素,其中各樣本不徹底相同,分別具備必定的表明性。框架
訓練過程分爲3個步驟:首先須要提取Haar特徵;而後將Haar特徵轉化成對應的弱分類器;最後從大量的弱分類器中迭代選擇出最優弱分類器。
(1)提取Haar特徵ide
經常使用的Haar特徵有4種,如圖2所示。固然也能夠在這4種特徵的基礎上設計出更多、更復雜的特徵。以大小爲24X24像素的訓練樣本爲例,上述4種特徵的總個數超過了160000個。這樣龐大的數字給後續的迭代訓練工做帶來了龐大的計算量,直接致使AdaBoost算法訓練過程極爲費時,這偏偏是算法須要改進的關鍵問題之一o函數
(2)生成弱分類器
每個Haar特徵都對應着一個弱分類器,每個弱分類器都是根據它所對應的Haar特徵的參數來定義的。利用上述Haar特徵的位置信息,對訓練樣本進行統計就能夠獲得對應的特徵參數。AdaBoost算法中所訓練的弱分類器是任何分類器,包括決策樹,神經網絡,隱馬爾科夫模型,若是弱分類器是線性神經網絡,那麼AdaBoost算法每次將構造多層感知器的一個節點。工具
(3)採用AdaBoost算法選取優化的弱分類器
AdaBoost算法訓練過程就是挑選最優弱分類器,並賦予權重過程,圖3是AdaBoost算法訓練示意圖。
用OpenCV自帶的adaboost程序訓練分類器:(原文在此,本文稍做修改)
重要!可能遇到的問題:
1.若是跑到某一個分類器時,幾個小時也沒有反應,並且顯示不出訓練百分比,這是由於你的負樣本數量太少,或者負樣本的尺寸過小,全部的負樣本在這個分類器都被reject了,程序進入不了下一個循環,果斷放棄吧。解決方法:負樣本儘可能要大一些,好比個人正樣本是40*15,共300個,負樣本是640*480,共500個。
2.讀取樣本時報錯:Negative or too large argument of CvAlloc function,網上說這個錯誤是由於opencv規定單幅iplimage的內存分配不能超過10000,但是個人每一個負樣本都不會超過這個大小,具體緣由不明。後來我把負樣本的數量減小,尺寸加大,這個問題就解決了。
3.訓練的過程可能常常出錯,耐心下來不要着急,我在訓練MRI分類器的時候失敗了無數次。失敗的時候有兩件事能夠作,第一,調整正負樣本的數量,再試。第二,調整負樣本的大小,祝你們好運。
1、簡介
目標檢測方法最初由Paul Viola [Viola01]提出,並由Rainer Lienhart [Lienhart02]對這一方法進行了改善。該方法的基本步驟爲: 首先,利用樣本(大約幾百幅樣本圖片)的 harr 特徵進行分類器訓練,獲得一個級聯的boosted分類器。分類器中的"級聯"是指最終的分類器是由幾個簡單分類器級聯組成。在圖像檢測中,被檢窗口依次經過每一級分類器, 這樣在前面幾層的檢測中大部分的候選區域就被排除了,所有經過每一級分類器檢測的區域即爲目標區域。
分類器訓練完之後,就能夠應用於輸入圖像中的感興趣區域的檢測。檢測到目標區域分類器輸出爲1,不然輸出爲0。爲了檢測整副圖像,能夠在圖像中移動搜索窗口,檢測每個位置來肯定可能的目標。 爲了搜索不一樣大小的目標物體,分類器被設計爲能夠進行尺寸改變,這樣比改變待檢圖像的尺寸大小更爲有效。因此,爲了在圖像中檢測未知大小的目標物體,掃描程序一般須要用不一樣比例大小的搜索窗口對圖片進行幾回掃描。
目前支持這種分類器的boosting技術有四種: Discrete Adaboost, Real Adaboost, Gentle Adaboost and Logitboost。"boosted" 即指級聯分類器的每一層均可以從中選取一個boosting算法(權重投票),並利用基礎分類器的自我訓練獲得。
根據上面的分析,目標檢測分爲三個步驟:
一、 樣本的建立
二、 訓練分類器
三、 利用訓練好的分類器進行目標檢測。
2、樣本建立
訓練樣本分爲正例樣本和反例樣本,其中正例樣本是指待檢目標樣本,反例樣本指其它任意圖片。
負樣本
負樣本能夠來自於任意的圖片,但這些圖片不能包含目標特徵。在用opencv自帶的adaboost程序訓練負樣本時,負樣本的大小不必定要與正樣本相同。負樣本由背景描述文件來描述。背景描述文件是一個文本文件,每一行包含了一個負樣本圖片的文件名(基於描述文件的相對路徑)。該文件建立方法以下:
採用Dos命令生成樣本描述文件。具體方法是在Dos下的進入你的圖片目錄,好比個人圖片放在D:\face\posdata下,則:
按Ctrl+R打開Windows運行程序,輸入cmd打開DOS命令窗口,輸入d:回車,再輸入cd D:\face\negdata進入圖片路徑,再次輸入dir /b > negdata.dat,則會圖片路徑下生成一個negdata.dat文件,打開該文件將最後一行的negdata.dat刪除,這樣就生成了負樣本描述文件。
正樣本
對於正樣本,一般的作法是先把全部正樣本裁切好,並對尺寸作規整(即縮放至指定大小)。
因爲HaarTraining訓練時輸入的正樣本是vec文件,因此須要使用OpenCV自帶的CreateSamples程序(在你所按照的opencv\bin下,若是沒有須要編譯opencv\apps\HaarTraining\make下的.dsw文件,注意要編譯release版的)將準備好的正樣本轉換爲vec文件。轉換的步驟以下:
1) 製做一個正樣本描述文件,用於描述正樣本文件名(包括絕對路徑或相對路徑),正樣本數目以及各正樣本在圖片中的位置和大小。典型的正樣本描述文件以下:
posdata/1(10).bmp 1 1 1 23 23
posdata/1(11).bmp 1 1 1 23 23
posdata/1(12).bmp 1 1 1 23 23
不過你能夠把描述文件放在你的posdata路徑(即正樣本路徑)下,這樣你就不須要加前面的相對路徑了。一樣它的生成方式能夠用負樣本描述文件的生成方法,最後用txt的替換工具將「bmp」所有替換成「bmp 1 1 1 23 23
」就能夠了,若是你的樣本圖片多,用txt替換會致使程序未響應,你能夠將內容拷到word下替換,而後再拷回來。bmp後面那五個數字分別表示圖片個數,目標的起始位置及其寬高。這樣就生成了正樣本描述文件posdata.dat。
2) 運行CreateSamples程序。若是直接在VC環境下運行,能夠在Project\Settings\Debug屬性頁的Program arguments欄設置運行參數。下面是一個運行參數示例:
-info D:\face\posdata\posdata.dat -vec D:\face\pos.vec -num 50 -w 20 -h 20
表示有50個樣本,樣本寬20,高20,正樣本描述文件爲posdata.dat,結果輸出到pos.vec。
或者在dos下輸入:
"D:\Program Files\OpenCV\bin\createsamples.exe" -info "posdata\posdata.dat" -vec data\pos.vec -num 50 -w 20 -h 20
運行完了會d:\face\data下生成一個*.vec的文件。該文件包含正樣本數目,寬高以及全部樣本圖像數據。
Createsamples程序的命令行參數:
命令行參數:
-vec <vec_file_name>
訓練好的正樣本的輸出文件名。
-img<image_file_name>
源目標圖片(例如:一個公司圖標)
-bg<background_file_name>
背景描述文件。
-num<number_of_samples>
要產生的正樣本的數量,和正樣本圖片數目相同。
-bgcolor<background_color>
背景色(假定當前圖片爲灰度圖)。背景色制定了透明色。對於壓縮圖片,顏色方差量由bgthresh參數來指定。則在bgcolor-bgthresh和bgcolor+bgthresh中間的像素被認爲是透明的。
-bgthresh<background_color_threshold>
-inv
若是指定,顏色會反色
-randinv
若是指定,顏色會任意反色
-maxidev<max_intensity_deviation>
背景色最大的偏離度。
-maxangel<max_x_rotation_angle>
-maxangle<max_y_rotation_angle>,
-maxzangle<max_x_rotation_angle>
最大旋轉角度,以弧度爲單位。
-show
若是指定,每一個樣本會被顯示出來,按下"esc"會關閉這一開關,即不顯示樣本圖片,而建立過程繼續。這是個有用的debug選項。
-w<sample_width>
輸出樣本的寬度(以像素爲單位)
-h《sample_height》
輸出樣本的高度,以像素爲單位。
到此第一步樣本訓練就完成了。恭喜你,你已經學會訓練分類器的五成功力了,我本身學這個的時候花了我一天的時間,估計你幾分鐘就學會了吧。
3、訓練分類器
樣本建立以後,接下來要訓練分類器,這個過程是由haartraining程序來實現的。該程序源碼由OpenCV自帶,且可執行程序在OpenCV安裝目錄的bin目錄下。
Haartraining的命令行參數以下:
-data<dir_name>
存放訓練好的分類器的路徑名。
-vec<vec_file_name>
正樣本文件名(由trainingssamples程序或者由其餘的方法建立的)
-bg<background_file_name>
背景描述文件。
-npos<number_of_positive_samples>,
-nneg<number_of_negative_samples>
用來訓練每個分類器階段的正/負樣本。合理的值是:nPos = 7000;nNeg = 3000
-nstages<number_of_stages>
訓練的階段數。
-nsplits<number_of_splits>
決定用於階段分類器的弱分類器。若是1,則一個簡單的stump classifier被使用。若是是2或者更多,則帶有number_of_splits個內部節點的CART分類器被使用。
-mem<memory_in_MB>
預先計算的以MB爲單位的可用內存。內存越大則訓練的速度越快。
-sym(default)
-nonsym
指定訓練的目標對象是否垂直對稱。垂直對稱提升目標的訓練速度。例如,正面部是垂直對稱的。
-minhitrate《min_hit_rate》
每一個階段分類器須要的最小的命中率。總的命中率爲min_hit_rate的number_of_stages次方。
-maxfalsealarm<max_false_alarm_rate>
沒有階段分類器的最大錯誤報警率。總的錯誤警告率爲max_false_alarm_rate的number_of_stages次方。
-weighttrimming<weight_trimming>
指定是否使用權修正和使用多大的權修正。一個基本的選擇是0.9
-eqw
-mode<basic(default)|core|all>
選擇用來訓練的haar特徵集的種類。basic僅僅使用垂直特徵。all使用垂直和45度角旋轉特徵。
-w《sample_width》
-h《sample_height》
訓練樣本的尺寸,(以像素爲單位)。必須和訓練樣本建立的尺寸相同。
一個訓練分類器的例子:
"D:\Program Files\OpenCV\bin\haartraining.exe" -data data\cascade -vec data\pos.vec -bg negdata\negdata.dat -npos 49 -nneg 49 -mem 200 -mode ALL -w 20 -h 20
訓練結束後,會在目錄data下生成一些子目錄,即爲訓練好的分類器。
恭喜你,你已經學會訓練分類器的九成功力了。
四:利用訓練好的分類器進行目標檢測。
這一步須要用到performance.exe,該程序源碼由OpenCV自帶,且可執行程序在OpenCV安裝目錄的bin目錄下。
performance.exe -data data/cascade -info posdata/test.dat -w 20 -h 20 -rs 30
performance的命令行參數以下:
Usage: ./performance
-data <classifier_directory_name>
-info <collection_file_name>
[-maxSizeDiff <max_size_difference = 1.500000>]
[-maxPosDiff <max_position_difference = 0.300000>]
[-sf <scale_factor = 1.200000>]
[-ni]
[-nos <number_of_stages = -1>]
[-rs <roc_size = 40>]
[-w <sample_width = 24>]
[-h <sample_height = 24>]
也能夠用opencv的cvHaarDetectObjects函數進行檢測:
CvSeq* faces = cvHaarDetectObjects( img, cascade, storage,1.1, 2, CV_HAAR_DO_CANNY_PRUNING,cvSize(40, 40) ); //3. 檢測人臉
注:OpenCv的某些版本能夠將這些目錄中的分類器直接轉換成xml文件。但在實際的操做中,haartraining程序卻好像永遠不會中止,並且沒有生成xml文件,後來在OpenCV的yahoo論壇上找到一個haarconv的程序,纔將分類器轉換爲xml文件,其中的緣由尚待研究。