歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> OpenCV_haar分類器的訓練

OpenCV_haar分類器的訓練

日期:2017/3/1 9:14:35   编辑:Linux編程

因為工作的原因,本人需要用到分類器來檢測目標,所以需要訓練自己的分類器

在這裡我就簡單的說下步驟和注意事項。

HaarTraining步驟

1.正負樣本處理

正樣本處理需要對正樣本進行歸一化處理,一般情況下可以用Photoshop對圖像進行尺寸統一處理,比如都是20*20或者24*24,其中其它尺寸比如240*15也可以做成樣本的,不要求是正方形,或者20*20,24*24,。這是取決於你的目標的形狀,不過正樣本的分辨率不要太高,太高的話在訓練時會內存分配不足引起crash

錯誤如下: OpenCV Error :insufficient memory <failed to allocate 250343435bytes> in cv::\OutOfMemoryError

圖1.1 正樣本分辨率太大時引起的內存分配不足的crash

不預先用Photoshop對正樣本進行處理時,還可以使用opencv_createSamples工具進行處理,其實就算用Photoshop對樣本進行過處理,在這裡還是會對樣本進行一次處理,Photoshop預先處理的好處就是樣本的位置都為0,0。那麼對正樣本描述文件處理時就比較簡單,特別是正樣本數量足夠大時,可以減少正樣本描述文件的出錯率,提高分類器的檢測率。

1.1正樣本描述文件

正樣本描述文件的創建如下:

一個.txt文件或者.dat文件裡面包含正樣本的信息,

結構:

包含正樣本圖片的相對路徑或者全路徑 正樣本中包含的正樣本數量 第一個正樣本的位置x y 第一個正樣本的寬和高w h 第二個正樣本的位置x y 第二個正樣本的寬和高w h …… 第n個正樣本的位置x y 第n個正樣本的寬和高w h

img01.jpg 1 0 0 20 20

img\\img02.jpg 1 0 0 24 24

e://img/img03.jpg 2 3 4 240 15 248 29 160 20

….

在這裡你就會明白為什麼要在之前用Photoshop對圖片進行處理,這樣的話,所有圖片都是只包含一個正樣本的統一尺寸的圖片,那麼正樣本描述文件就像下面那樣:

img01.jpg 1 0 0 20 20

img02.jpg 1 0 0 20 20

img03.jpg 1 0 0 20 20

……

既然是是統一的話,就可以用批處理來完成:

在Windows下用命令: dir imgDir /b > imgDiscr.txt

(在linux下用: ls imgDir >imgDiscr.txt ,也可以保存為.sh文件,這樣不用每次輸入命令)

我是直接保存為.bat文件,這樣每次不用打命令,而是點擊就生成包含所有正樣本圖片名的文件imgDiscr.txt :

img01.jpg

img02.jpg

img03.jpg

….

然後用編輯器打開,把jpg替換成jpg 1 0 0 20 20

就可以快速生成正樣本描述文件。

1.2負樣本描述文件的生成

和正樣本一樣,不過不需要對負樣本圖片進行處理,只要負樣本圖片不比正樣本圖片的分辨率小就行,負樣本描述文件只需要包含圖片路徑名:

non-img01.jpg

non-img02.jpg

non-img03.jpg

….

2.opencv_createsamples生成正樣本.vec文件

分類器在訓練時並不會直接處理正樣本描述文件,而是包含正樣本的.vec文件,這是一個用matlab函數生成的向量文件。

參數的設定如下:

opencv_createsamples.exe -info imgDiscr.txt -vec samples.vec -num 68 -w 20-h 20

命令行參數:

  • [-vec <vec_file_name>] 輸出文件,內含用於訓練的正樣本
  • [-img <image_file_name>] 輸入圖像文件名(例如一個公司的標志
  • [-bg <background_file_name>] 背景圖像的描述文件,文件中包含一系列的圖像文件名,這些圖像將被隨機選作物體的背景。
  • [-mun <number_of_samples>]生成的正樣本的數目。
  • [-maxxangle <max_x_rotation_angle>]X軸最大旋轉角度,必須以弧度為單位。
  • [-maxyangle <max_y_rotation_angle>]Y軸最大旋轉角度,必須以弧度為單位。
  • [-maxzangle <max_z_rotation_angle>]Z軸最大旋轉角度,必須以弧度為單位。
  • [-w <sample_width >] 輸出樣本的寬度(以像素為單位)
  • [-h <sample_height >]輸出樣本的高度(以像素為單位)。

其中-num的數值應該為總的正樣本數,也就是正樣本描述文件中第二列數字總和

-w -h是輸出圖像的寬和高,這裡也會對正樣本進行歸一化處理,其中我們之前用Photoshop對圖像進行過歸一化處理,如果沒有,那麼在這裡createsample工具也會對正樣本進行歸一化處理,所有的正樣本大小都是一樣的。而且,之前Photoshop歸一化為20個像素後,在這裡設置為24個像素,那麼生成的.vec向量文件裡面的圖像是24個像素的。

3.haarTraining訓練分類器

opencv_haarTraining訓練器是一個被淘汰的訓練器,在2.4.9裡面還有,2.4.10後就沒有了,不過用opencv_traincascade訓練出來的分類器在示例程序中無法使用,而且3.10的opencv_traincascade在使用時出現問題,所以迫不得已找回了以前的haarTraining來使用。其中opencv_traincascade出現的錯誤如下:

Train dataset for temp stage can not be filled. Branch training terminated

stackoverflow上的說是描述文件是在Windows下生成的,結尾是/r/n,而linux下的描述文件後面是/r沒有/n,所有導致讀取不到圖像文件,但是在linux下訓練時還是會出現問題,所以,我覺得問題不在描述文件上。訓練分類器用以下命令:

opencv_haartraining.exe -data block_xml/ -vec samples.vec -bg non-imgDiscr.txt -nstages 20 -nsplits 2 -minhitrate 0.999 -maxfalsealarm 0.5 -npos 200 -nneg 20 -w 240 -h 15 -mem 1024 -eqw 1 -mode ALL -bt GAB -minpos 32

這裡的正樣本數量為200,負樣本數量為20,樣本的寬為240,高為15

正樣本最小命中率為0.999,因為級聯-nstages為20,所以0.999^20 = 0.98 負樣本的最大錯誤率為0.5 經過20個級聯後錯誤率為0.5^20 = 0.0000009536
基本參數:

" -data <dir_name>\n"
 " -vec <vec_file_name>\n"
 " -bg <background_file_name>\n"
 " [-npos <number_of_positive_samples = %d>]\n"
 " [-nneg <number_of_negative_samples = %d>]\n"
 " [-nstages <number_of_stages = %d>]\n"
 " [-nsplits <number_of_splits = %d>]\n"
 " [-mem <memory_in_MB = %d>]\n"
 " [-sym (default)] [-nonsym]\n"
 " [-minhitrate <min_hit_rate = %f>]\n"
 " [-maxfalsealarm <max_false_alarm_rate = %f>]\n"
 " [-weighttrimming <weight_trimming = %f>]\n"
 " [-eqw]\n"
 " [-mode <BASIC (default) | CORE | ALL>]\n"
 " [-w <sample_width = %d>]\n"
 " [-h <sample_height = %d>]\n"
 " [-bt <DAB | RAB | LB | GAB (default)>]\n"
 " [-err <misclass (default) | gini | entropy>]\n"
 " [-maxtreesplits <max_number_of_splits_in_tree_cascade = %d>]\n"
 " [-minpos <min_number_of_positive_samples_per_cluster = %d>]\n",

要注意的是 –nneg 的參數 = 實際的負樣本數 * maxfalsealarm

因為第一次訓練完成後,第二個級聯的負樣本數其實並沒有百分百留下,其中有誤判的負樣本沒有加載,所以-nneg如果為實際的負樣本數,那麼程序很有可能進入死循環,如果樣本數不大,但是幾個小時後還沒有動靜,那麼就是進入死循環了,像上面的200個正樣本,20個負樣本基本上前10個級聯是一分鐘內完成,後面的級聯幾分鐘一個,如果超過十分鐘沒有動靜,那麼就是進入死循環了。在這裡,參數設置不正確,那麼就會訓練不成功,還有一個進入死循環的可能就是虛警率一直不能下來,就是maxfalsealarm的值一直居高不下,所以訓練器一直在跑,導致結果一直不能停,如果訓練一段時間,還在訓練,參數沒有問題的話,那麼就應該適當的設置級聯的數量,來停止訓練,得到分類器。

用opencv_traincascade來訓練的話可以結合TBB來多核處理,在

編譯opencv時加入TBB。

用opencv_haarTraining訓練出來的分類器會保存在當前目錄下用-data的參數命名的xml文件裡。

訓練的過程可以隨時停止,重新訓練時,訓練器會讀取之前的參數,從停止的地方開始。

訓練結束:

OpenCV官方教程中文版(For Python) PDF http://www.linuxidc.com/Linux/2015-08/121400.htm

Ubuntu Linux下安裝OpenCV2.4.1所需包 http://www.linuxidc.com/Linux/2012-08/68184.htm

Ubuntu 12.04 安裝 OpenCV2.4.2 http://www.linuxidc.com/Linux/2012-09/70158.htm

CentOS下OpenCV無法讀取視頻文件 http://www.linuxidc.com/Linux/2011-07/39295.htm

Ubuntu 12.04下安裝OpenCV 2.4.5總結 http://www.linuxidc.com/Linux/2013-06/86704.htm

Ubuntu 10.04中安裝OpenCv2.1九步曲 http://www.linuxidc.com/Linux/2010-09/28678.htm

基於QT和OpenCV的人臉識別系統 http://www.linuxidc.com/Linux/2011-11/47806.htm

[翻譯]Ubuntu 14.04, 13.10 下安裝 OpenCV 2.4.9 http://www.linuxidc.com/Linux/2014-12/110045.htm

OpenCV的詳細介紹:請點這裡
OpenCV的下載地址:請點這裡

Copyright © Linux教程網 All Rights Reserved