opencv 2.1網上查的另一種資料
訓練分類器成功,在此與大家分享。
參考英文資料網址: http://note.sonots.com/scisoftware/haartraining.html#e134e74e
樣本訓練要求
1、杯子的背景要統一嗎,因為有些背景是白色,有些是淡淡的背景色,還有些深色的背景色
答:背景色要統一
2、整個圖的大小就是最外面一個框框起來那麼大,
問題是:我需要在原圖基礎上截圖嗎,如:隻把紅框框起來的那部分截出來???
答:不用的
3、那圖檔是256色的還是彩色的呢?
答:灰階最佳
5、一般來說,訓練分類器用的什麼 圖檔 就用什麼 圖檔作測試
即來源圖檔分别用于訓練和測試
6、那正樣本選擇方面有沒有要求,如玻璃杯
當然有要求。
最好各種形狀的玻璃杯都有樣本,每種玻璃杯從不同角度拍攝的樣本都有
7、那網上截些有關玻璃杯的圖可以嗎?大小是要歸一化的
可以的。網上的圖像實際上也來源于生活或科研拍攝的
其實可以不是圖檔的歸一化,還可以是特征的歸一化
歸一化的話可以根據緩需求,不同應用場合就有不同的歸一化方法
8、那關于杯子這個正樣本,我要弄大約多少張圖檔呀?
樣本要多,當然并不是越多越好,而是每一張都有代表性,能反映一定意義
9、負樣本最好含有正樣本中的背景部分
訓練失敗的原因很多:
1、負樣本數目太少,導緻adaboost算法漢有跳出死循環,
2、負樣本之間重複部分過多,或正樣本尺寸過大,導緻訓練分類器時内在溢出。
.vec檔案裡的東西是用二進制的形式表示的。
首先寫的是樣本的數量,然後是樣本大小width*height,後面就是圖檔像素值。
在opencv下的cvsamples.cpp就能看的很清楚了。
本文現在正在做人頭檢測。視訊中的人頭尺寸,光照,角度都很不相同。
1. 請問haar訓練中正樣本是不是隻能是在光照尺寸和角度都一緻的情況下進行訓練?
正樣本的光照可以是有變化的,正樣本應該保留一些樣本以外的背景,但不能過大,角度的話,人臉轉90度都還可以接受。
其實你正樣本的種類(不同角度.不同光照.不同人臉)越多,就需要更多的矩形特徵來作分類。
2.正負樣本需要一樣的大小麼?
人臉建議使用20*20,大小要盡量統一,這樣在做description txt file時,比較友善。人臉在圖片中的位置盡量也相同。
3.有人說正負樣本數量比例最好是7:3,也有人說正負樣本須一樣多。這是怎麼回事?
我怎麼聽說 正:負=1:3比較好。建議你可以先試試看1000:3000應該不用花太多時間訓練。
4.在訓練中,本人發現了一種情況:如果正負樣本差别較小,即負樣本從待檢測視訊圖像中的背景擷取,并且與正樣本一樣大的話,訓練就會在某一個節點上停下來,并且幾天也過不了這個節點;而如果負樣本與正樣本差别很大(尺寸與取樣上都差别很大)的話,訓練結束比較快,但是用得到的xml檔案去做檢測的話,效果很不好。請問這是不是沖突,該怎麼解決?
正負樣本照理說應該不會差別不大,除非你是要偵測笑臉/非笑臉,另外可能是你負樣本太少,是以false alarm數值太高,是以haartraining 沒有正常terminate
5.參數stage一般設定多大?
我目前使用如下指令
opencv_haartraining.exe -data "d:\training0421\20s" -vec "d:\training0421\positive\positives.vec" -bg "d:\training0421\negative\negative.txt" -npos 1681 -nneg 3406 -nstages 20 -nsplits 2 -minhitrate 0.995 -maxfalsealarm 0.5 -mode all -mem 2000 -w 20 -h 20
使用profermance來測試原始訓練樣本(200*200p)可以有八成的hitrate,false大概幾十個。
整個過程分為兩步:
1. 建立樣本
2. 訓練分類器
3、 利用訓練好的分類器進行目标檢測。
現在讓我一一講述。
◆ 樣本分兩種: 正樣本與負樣本(也有人翻譯成:正例樣本和反例樣本),其中正樣本是指待檢目标樣本(例如人臉,汽車,鼻子等),負樣本指其它任意圖檔。
◆ 所有樣本圖檔都應該有同一尺寸,如20 * 20,并放在相應檔案目錄下,
◆ 集合檔案格式(collection file format)和描述檔案格式(description file format)
集合檔案格式(collection file format)就是如下形的描述檔案:
[filename]
…
描述檔案格式(description file format)就是如下形的描述檔案:
[filename] [# of objects] [[x y width height] [... 2nd object] ...]
….
(x, y) 指左上角的坐标,width和 height 分别是樣本的寬和高,這裡我的圖檔是20*20的,是以兩個值都是20
◆ 負樣本用集合檔案格式描述,正樣本用描述檔案格式描述!(這點網上很多文章都搞錯了!)
▼建立樣本步驟:
一. 把所有正樣本圖檔放在posdata的檔案夾下,把所有負樣本圖檔放在negdata檔案夾下
(這裡我以人臉圖檔樣本為例)
(注:以上這些 20*20 的圖檔均來自mit人臉庫,可以在csdn下載下傳)
二. 分别為正樣本和負樣本建立描述檔案
a. 為正樣本建立描述檔案格式檔案info.txt,并且把這個檔案放在與樣本圖檔同一目錄下,例如我的目錄為c:/opencv2.1/bin/posdata
a) 在指令行下 輸入以下指令: dir /b > info.txt
b) 打開info.txt, 按ctrl+h, 把所有的bmp 換成 bmp 1 0 0 20 20
c) 删除info.txt最後一行的 “info.txt”
d) 結果如下:(1代表一個檔案,0 0 20 20表示這個檔案的2個頂點位置坐标)
b. 為負樣本建立集合檔案格式檔案bg.txt, 并且把這個檔案放在與樣本圖檔同一目錄下,例如我的目錄為i:/negdata
a) 在指令行下 輸入以下指令: dir /b > bg.txt
b) 删除bg.txt最後一行的 “bg.txt”
c) 結果如下:
三. 建立樣本。
opencv 自帶有建立樣本的exe 檔案,在 …/opencv2.1/bin 目錄下, 這裡我建立120個sample:
指令是: opencv_createsamples.exe -info e:\test\posdata0\info.txt -vec e:\test\posdata0\pos.vec -num 120 -w 20 -h 20
如圖:
結果如圖:
(關于 opencv_createsamples.exe 的參數用法,在參考英文資料網址http://note.sonots.com/scisoftware/haartraining.html#e134e74e,裡有詳細介紹;
需要說明的是,我這裡用的參數并沒有 –bg, 因為根據那份文檔,有了 –vec 和 –info 之後,就表示:create training samples from some (從很多正樣本中建立sample, 沒有distortions)
經曆千辛萬苦,我們終于看到sample被建立成功了,接下來的工作就簡單多了
▼訓練分類器
還是在…/opencv2.1/bin目錄下,輸入指令:
opencv_haartraining.exe -data e:\test\data0\cascade0 -vec e:\test\posdata0\pos.vec -bg e:\test\negdata0\negdata0.txt -npos 120 -nneg 120 -nsplits 2 -mem 512 -nonsym -w 20 -h 20 -minpos 100 -nstages 4
回車
(注意:
1. 參數-vec 一定要是剛剛建立樣本産生的a.vec,且把完整路徑也寫上去,我試過用相對路徑,但總會訓練失敗; bg.txt 也要用絕對路徑;
2. –w 和 –h 都要寫上與樣本大小的一緻的尺寸
3. 若遇到“記憶體什麼不能read”的問題,很有可能是bg.txt的格式有誤,回去
4. 關于 opencv_haartraining.exe 的參數用法,在參考英文資料網址http://note.sonots.com/scisoftware/haartraining.html#e134e74e,裡有詳細介紹
)
結果如下:
(可能實際結果與上圖有出入, 但看到最後的
,就說明訓練成功了。
在e:\test\data0目錄會生成一份cascade0.xml文檔,這個就是我們想要的結果了!
============================================================================
opencv訓練分類器制作xml文檔之一
我的問題:有了opencv自帶的那些xml人臉檢測文檔,我們就可以用cvload()這個函數加載他們,讓他們對我們的人臉進行檢測,但是,現在生活中的計算機視覺并不遠遠是檢測人臉,還有很多物品需要識别,是以,能不能自己做個xml的檢測文檔,用它來檢測自己需要的東西呢?例如,檢測一個可樂瓶!
問題解決:
首先了解下,目标檢測分為三個步驟:
1、 樣本的建立
2、 訓練分類器
一,樣本的建立:
(1)收集訓練樣本:
訓練樣本包括正樣本和負樣本。正樣本,通俗點說,就是圖檔中隻有你需要的目标。而負樣本的圖檔隻要其中不含有目标就可以了。但需要說明的是,負樣本也并非随便選取的。例如,你需要檢測的目标是汽車,那麼正樣本就應該是僅僅含有汽車的圖檔,而負樣本顯然不能是一些包含天空的,海洋的,風景的圖檔。因為你最終訓練分類器的目的是檢測汽車,而汽車應該出現在馬路上。也就是說,分類器最終檢測的圖檔應該是那些包含馬路,交通标志,建築物,廣告牌,汽車,機車,三輪車,行人,自行車等在内的圖檔。很明顯,這裡的負樣本應該是包含機車、三輪車、自行車、行人、路面、灌木叢、花草、交通标志、廣告牌等。
另外,需要提醒的是,adaboost方法也是機器學習中的一個經典算法,而機器學習算法的前提條件是,測試樣本和訓練樣本獨立同分布。所謂的獨立同分布,可以簡單了解為:訓練樣本要和最終的應用場合非常接近或者一緻。否則,基于機器學習的算法并不能保證算法的有效性。此外,足夠的訓練樣本(至少得幾千張正樣本、幾千張負樣本)也是保證訓練算法有效性的一個前提條件。
訓練樣本分為正例樣本和反例樣本,其中正例樣本是指待檢目标樣本(例如可樂瓶,人臉等),反例樣本指其它任意圖檔,所有的樣本圖檔都被歸一化為同樣的尺寸大小(例如,20x20)。
1 、負樣本(反例樣本)可以來自于任意的圖檔,但這些圖檔不能包含目标特征。
負樣本由背景描述檔案來描述。背景描述檔案是一個文本檔案,每一行包含了一個負樣本圖檔的檔案名(基于描述檔案的相對路徑)。該檔案必須手工建立。
2,正樣本
現在,我們來看正樣本的建立步驟:
正樣本由程式createsample程式來建立。該程式的源代碼由opencv給出,并且在bin目錄下包含了這個可執行的程式。
正樣本可以由單個的目标圖檔或者一系列的事先标記好的圖檔來建立。
createsamples程式的指令行參數:
指令行參數:
-vec <vec_file_name>
訓練好的正樣本的輸出檔案名。
-img<image_file_name>
源目标圖檔(例如:一個公司圖示)
-bg<background_file_name>
背景描述檔案。
-num<number_of_samples>
要産生的正樣本的數量,和正樣本圖檔數目相同。 -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 ,寬度,高度)。
下面是一個建立樣本的例子:
假定我們要進行人臉的檢測,有18個正樣本圖檔檔案face00001.bmp,…face00100.bmp;有45個背景圖檔檔案:b1_00001.bmp, …b1_00200.bmp,檔案目錄結構如下:
e:\test\negdata\
face0001.bmp
……
face0018.bmp
info.txt
e:\test\posdata
b1_001.bmp
……
b1_0045.bmp
negdata.dat
正樣本描述檔案info.txt的内容如下:
face00001.bmp 1 0 0 20 20
……
face00100.bmp 1 0 0 20 20
背景(負樣本)描述檔案negdata.txt的内容如下:
b1_00001.bmp ……
b1_00200.bmp
圖檔imag1.bmp包含了單個目标對象實體,矩形為(0,0,20,20)。
注意:要從圖檔集中建立正樣本,要用-info參數而不是用-img參數。
-info <collect_file_name>
标記特征的圖檔集合的描述檔案。在cmd視窗下來進行樣本的建立:
c:\program files\opencv\bin>createsamples -info e:\test\posdata\info.txt -vec e:\test\posdata\pos.vec -num 18 -w 20 -h 20【解釋下】。。。。
小貼士1:
可以采用dos指令生成樣本描述檔案(一般樣本圖檔上萬幅),在dos下進入圖檔目錄,輸入dir /b *.bmp > negdata.txt, 則會在此目錄中産生一個negdata.txt,檔案中包含所有目前目錄下的檔案名,就可以建成負樣本描述檔案。對于正樣本描述檔案,方法同負樣本,隻要把bmp替換成1 0 0 20
20即可。如果樣本圖檔太多,在txt中替換會導緻程式無法響應,可以先把内容拷貝到word中替換後再拷貝回來。
小貼士2:
一些處理後的人臉圖檔的網址
http://vasc.ri.cmu.edu/idb/html/face/frontal_images/
http://www.pascal-network.org/challenges/voc/databases.html#voc2005_1
三、訓練分類器
樣本建立之後,接下來要訓練分類器,這個過程是由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>
訓練樣本的尺寸,(以像素為機關)。必須和訓練樣本建立的尺寸相同。
一個訓練分類器的例子:
c:\program files\opencv\bin>haartraining -data e:\test\data\cascade -vec e:\test\posdata\pos.vec -bg e:\test\negdata\negdata.txt -npos 18 -nneg 45 -nsplits 1 -mem 512 -mode all -w 20 -h 20 -minhitrage 0.998 -maxfalsealarm 0.5 -nstages
訓練開始,如下圖,可能會一小段時間才訓練完成。
在bin目錄會生成一份可愛的data.xml文檔,這個就是我們想要的結果了!
訓練結束後,會在目錄data下生成一些子目錄,即為訓練好的分類器。
訓練結束後,還要使用haarconv.exe生成xml檔案,可以通過下列網頁下載下傳。
http://www.opencv.org.cn/forum/viewtopic.php?t=5181
重要!可能遇到的問題:
1.如果跑到某一個分類器時,幾個小時也沒有反應,而且顯示不出訓練百分比,這是因為你的負樣本數量太少,或者負樣本的尺寸太小,所有的負樣本在這個分類器都被reject了,程式進入不了下一個循環,果斷放棄吧。解決方法:負樣本盡量要大一些,比如我的正樣本是40*15,共300個,負樣本是640*480,共500個。(我當時的錯誤就出現在這,把負本改大後,就成功了)
2.讀取樣本時報錯:negative or too large argument of cvalloc function,網上說這個錯誤是因為opencv規定單幅iplimage的記憶體配置設定不能超過10000,可是我的每個負樣本都不會超過這個大小,具體原因不明。後來我把負樣本的數量減少,尺寸加大,這個問題就解決了。
3.訓練的過程可能經常出錯,耐心下來不要着急,我在訓練mri分類器的時候失敗了無數次。失敗的時候有兩件事可以做,第一,調整正負樣本的數量,再試。第二,調整負樣本的大小,祝大家好運。
=============================================================================================
opencv haar訓練--訓練樣本(4)
1.海爾訓練
現在,我們使用haartraining.exe來訓練我們自己的分類器。訓練語句如下:
[plain] view
plaincopyprint?
usage: ./haartraining
-data <dir_name>
-vec <vec_file_name>
-bg <background_file_name>
[-npos <number_of_positive_samples = 2000>]
[-nneg <number_of_negative_samples = 2000>]
[-nstages <number_of_stages = 14>]
[-nsplits <number_of_splits = 1>]
[-mem <memory_in_mb = 200>]
[-sym (default)] [-nonsym]
[-minhitrate <min_hit_rate = 0.995000>]
[-maxfalsealarm <max_false_alarm_rate = 0.500000>]
[-weighttrimming <weight_trimming = 0.950000>]
[-eqw]
[-mode <basic (default) | core | all>]
[-w <sample_width = 24>]
[-h <sample_height = 24>]
[-bt <dab | rab | lb | gab (default)>]
[-err <misclass (default) | gini | entropy>]
[-maxtreesplits <max_number_of_splits_in_tree_cascade = 0>]
[-minpos <min_number_of_positive_samples_per_cluster = 500>]
kuranov et. al. 指出,20*20的樣本識别的正确率最高。另外,對于18*18的尺寸,四分裂節點表現最好。而對于20*20的樣本,兩節點顯然更好。分裂節點數分别是2、3或4的弱樹分類器間的差小于它們的中間節點。
此外,關于20階訓練有個說法。假設我的測試集合代表了學習任務,我可以期望一個報錯率是0.5^20≈9.6e-07,識對率是0.999^20≈0.98。
是以,使用20*20的樣本大小,并且nsplit=2, nstages=20, minhitrate=0.9999(default: 0.995), maxfalsealarm=0.5(default: 0.5), weighttrimming=0.95(default: 0.95)是比較優的組合。
$ haartraining -data haarcascade -vec samples.vec -bg negatives.dat -nstages 20 -nsplits 2 -minhitrate 0.999 -maxfalsealarm 0.5 -npos 7000 -nneg 3019 -w 20 -h 20 -nonsym -mem 512 -mode all
"-nonsym"選項用于沒有垂直(左-右)對稱的對象類。如果對象類是垂直對稱的,例如正臉,則用"-sym (default)"。這樣會增大運算速度,因為類海爾特征隻有一半投入使用。
"-mode all"使用了類海爾特征的擴充集。預設隻使用豎直特征,all除了能使用豎直特征,還能使用轉角為45°的特征集合。
"-mem 512"是以mb為機關的預計算可使用的記憶體大小。預設是200mb。
另外還有一些選項沒有用到:
[-bt <dab | rab | lb | gab (default)>]
[-err <misclass (default) | gini | entropy>]
[-maxtreesplits <max_number_of_splits_in_tree_cascade = 0>]
[-minpos <min_number_of_positive_samples_per_cluster = 500>]
#你可以使用openmp(multi-processing).
#一次訓練持續三天。
2.生成xml檔案
當海爾訓練過程完全結束,它将會生成一個xml檔案。
如果你想要将一個中級海爾訓練輸出目錄樹轉化為一個xml檔案,在目錄opencv/samples/c/convert_cascade.c下有個程式可供使用。
輸入的格式為:
$ convert_cascade --size="<sample_width>x<sampe_height>" <haartraining_ouput_dir> <ouput_file>
舉例:
$ convert_cascade --size="20x20" haarcascade haarcascade.xml