介紹
使用級聯分類器工作包括兩個階段:訓練和檢測。 檢測部分在OpenCVobjdetect 模塊的文檔中有介紹,在那個文檔中給出了一些級聯分類器的基本介紹。當前的指南描述了如何訓練分類器:准備訓練數據和運行訓練程序。參考:http://jingyan.baidu.com/article/4dc40848f50689c8d946f197.html
利用OpenCV自帶的haar training程序訓練一個分類器,需要經過以下幾個步驟:
(1)收集訓練樣本:
訓練樣本包括正樣本和負樣本。正樣本,通俗點說,就是圖片中只有你需要的目標。而負樣本的圖片只要其中不含有目標就可以了。但需要說明的是,負樣本也並非隨便選取的。例如,你需要檢測的目標是汽車,那么正樣本就應該是僅僅含有汽車的圖片,而負樣本顯然不能是一些包含天空的,海洋的,風景的圖片。因為你最終訓練分類器的目的是檢測汽車,而汽車應該出現在馬路上。也就是說,分類器最終檢測的圖片應該是那些包含馬路,交通標志,建築物,廣告牌,汽車,摩托車,三輪車,行人,自行車等在內的圖片。很明顯,這里的負樣本應該是包含摩托車、三輪車、自行車、行人、路面、灌木叢、花草、交通標志、廣告牌等。
另外,需要提醒的是,adaboost方法也是機器學習中的一個經典算法,而機器學習算法的前提條件是,測試樣本和訓練樣本獨立同分布。所謂的獨立同分布,可以簡單理解為:訓練樣本要和最終的應用場合非常接近或者一致。否則,基於機器學習的算法並不能保證算法的有效性。此外,足夠的訓練樣本(至少得幾千張正樣本、幾千張負樣本)也是保證訓練算法有效性的一個前提條件。
這里,假設所有的正樣本都放在 /pos文件夾下,所有的負樣本都放在 /neg文件夾下;
(2)對所有的正樣本進行尺寸歸一化:
上一步收集到的正樣本,有很多的尺寸大小,有的是200*300,有的是500*800...尺寸歸一化的目的,就是把所有的圖片都縮放到同一大小。比如,都縮放到50*60的大小。(程序或者光影魔術手都可以)
(3)生成正樣本描述文件:
所謂的正樣本描述文件,其實就是一個文本文件,只不過,很多人喜歡將這個文件的后綴改成.dat而已。正樣本描述文件中的內容包括:文件名 目標個數 目標在圖片中的位置(x,y,width,height)典型的正樣本描述文件如下所示:0.jpg 1 0 0 30 40….
假如,\pos文件夾下有5000個正樣本圖片,每個圖片中僅有一個目標。命令行下 dir /b > pos.dat生成一個pos.dat文件作為正樣本描述文件。
(4)創建正樣本vec文件
由於haarTraining訓練的時候需要輸入的正樣本是vec文件,所以需要使用createsamples程序來將正樣本轉換為vec文件。(例如:f:\pos\pos.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》
輸出樣本的高度,以像素為單位。
(5) 創建負樣本描述文件
在保存負樣本的文件夾下生成一個負樣本描述文件,具體步驟同(3),此處不再贅敘;
(6)進行樣本訓練
該步驟通過調用OpenCV\bin目錄下的haartraining程序(新版本的opencv改名為opencv_haartraining)來完成。其中,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下生成一些子目錄,即為訓練好的分類器。
(7) 生成xml文件
上一步在進行haartraining的時候,會在data目錄下生成一些目錄及txt文件,我們需要調用opencv\bin\haarconv.exe將這些txt文件轉換為xml文件,也就是所謂的分類器。
至此,分類器的訓練工作已完成。剩下的,就是在程序中加載xml文件,並調用相應的函數接口來實現分類檢測的作用了。
其實這個方法有點老了,新一點有這個:http://blog.csdn.net/liulina603/article/details/8598681
