目標檢測方法最初由Paul Viola [Viola01]提出,並由Rainer Lienhart [Lienhart02]對這一方法進行了改善。該方法的基本步驟為: 首先,利用樣本(大約幾百幅樣本圖片)的 harr 特征進行分類器訓練,得到一個級聯的boosted分類器。
分類器中的"級聯"是指最終的分類器是由幾個簡單分類器級聯組成。在圖像檢測中,被檢窗口依次通過每一級分類器, 這樣在前面幾層的檢測中大部分的候選區域就被排除了,全部通過每一級分類器檢測的區域即為目標區域。 分 類器訓練完以后,就可以應用於輸入圖像中的感興趣區域(與訓練樣本相同的尺寸)的檢測。檢測到目標區域(汽車或人臉)分類器輸出為1,否則輸出為0。為了 檢測整副圖像,可以在圖像中移動搜索窗口,檢測每一個位置來確定可能的目標。 為了搜索不同大小的目標物體,分類器被設計為可以進行尺寸改變,這樣比改變待檢圖像的尺寸大小更為有效。所以,為了在圖像中檢測未知大小的目標物體,掃描 程序通常需要用不同比例大小的搜索窗口對圖片進行幾次掃描。 目前支持這種分類器的boosting技術有四種: Discrete Adaboost, Real Adaboost, Gentle Adaboost and Logitboost。 "boosted" 即指級聯分類器的每一層都可以從中選取一個boosting算法(權重投票),並利用基礎分類器的自我訓練得到。 根據上面的分析,目標檢測分為三個步驟: 1、 樣本的創建 2、 訓練分類器 3、 利用訓練好的分類器進行目標檢測。 二、樣本創建 訓練樣本分為正例樣本和反例樣本,其中正例樣本是指待檢目標樣本(例如人臉或汽車等),反例樣本指其它任意圖片,所有的樣本圖片都被歸一化為同樣的尺寸大小(例如,20x20)。 負樣本 負樣本可以來自於任意的圖片,但這些圖片不能包含目標特征。負樣本由背景描述文件來描述。背景描述文件是一個文本文件,每一行包含了一個負樣本圖片的文件名(基於描述文件的相對路徑)。該文件必須手工創建。 e.g: 負樣本描述文件的一個例子: 假定目錄結構如下: /img img1.jpg img2.jpg bg.txt 則背景描述文件bg.txt的內容為: img/img1.jpg img/img2.jpg 正樣本 正樣本由程序craatesample程序來創建。該程序的源代碼由OpenCV給出,並且在bin目錄下包含了這個可執行的程序。 正樣本可以由單個的目標圖片或者一系列的事先標記好的圖片來創建。 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》 輸出樣本的高度,以像素為單位。 注:正樣本也可以從一個預先標記好的圖像集合中獲取。這個集合由一個文本文件來描述,類似於背景描述文件。每一個文本行對應一個圖片。每行的第一個元素是圖片文件名,第二個元素是對象實體的個數。后面緊跟着的是與之匹配的矩形框(x, y, 寬度,高度)。 下面是一個創建樣本的例子: 假定我們要進行人臉的檢測,有5個正樣本圖片文件img1.bmp,…img5.bmp;有2個背景圖片文件:bg1.bmp,bg2.bmp,文件目錄結構如下: positive img1.bmp …… Img5.bmp negative bg1.bmp bg2.bmp info.dat bg.txt 正樣本描述文件info.dat的內容如下: Positive/imag1.bmp 1 0 0 24 28 …… Positive/imag5.bmp 1 0 0 24 28 圖片img1.bmp包含了單個目標對象實體,矩形為(0,0,24,28)。 注意:要從圖片集中創建正樣本,要用-info參數而不是用-img參數。 -info <collect_file_name> 標記特征的圖片集合的描述文件。 背景(負樣本)描述文件的內容如下: nagative/bg1.bmp nagative/bg2.bmp 我們用一個批處理文件run.bat來進行正樣本的創建:該文件的內容如下: cd e:\face\bin CreateSamples -vec e:\face\a.vec -info e:\face\info.dat -bg e:\face\bg.txt -num 5 -show -w 24 -h 28 其中e:\face\bin目錄包含了createsamples可執行程序,生成的正樣本文件a.vec在e:\face目錄下。 三、訓練分類器 樣本創建之后,接下來要訓練分類器,這個過程是由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》 訓練樣本的尺寸,(以像素為單位)。必須和訓練樣本創建的尺寸相同。 一個訓練分類器的例子: 同上例,分類器訓練的過程用一個批處理文件run2.bat來完成: cd e:\face\bin haartraining -data e:\face\data -vec e:\face\a.vec -bg e:\face\bg.txt -npos 5 -nneg 2 -w 24 -h 28 訓練結束后,會在目錄data下生成一些子目錄,即為訓練好的分類器。 注: OpenCv的某些版本可以將這些目錄中的分類器直接轉換成xml文件。但在實際的操作中,haartraining程序卻好像永遠不會停止,而且沒有生 成xml文件,后來在OpenCV的yahoo論壇上找到一個haarconv的程序,才將分類器轉換為xml文件,其中的原因尚待研究。 |