訓練自己haar-like特徵分類器並識別物體(1)

來源:互聯網
上載者:User

本系列文章旨在學習如何在opencv中基於haar-like特徵訓練自己的分類器,並且用該分類器用於模式識別。該過程大致可以分為一下幾個大步驟:

1.準備訓練樣本圖片,包括正例及反例樣本

2.產生樣本描述檔案

3.訓練樣本

4.目標識別

=================

本文主要對步驟1、步驟2進行說明。

1.準備訓練樣本圖片,包括正例及反例樣本

1)正樣本的採集

  所謂正樣本,是指只包含待識別的物體的圖片,一般是一些局部的圖片,且最好能轉化為灰階圖。比如,若你想識別人臉,則正樣本應儘可能只包含人臉,可以留一點周邊的背景但不要過多。在正樣本的採集上,我們有兩種圖形標定工具可以使用:(1)opencv的imageClipper (2)objectMarker。這兩個工具都支援傻瓜式地對圖片中的物體進行矩形標定,可以自動產生樣本說明檔案,自動逐幀讀取檔案夾內的下一幀。我用的是objectMarker。如果你找不到這個軟體,可以留下郵箱,我發給你。
  在標定的時候盡量保持長寬比例一致,也就是盡量用接近正方形的矩形去標定待識別的物體,至於正方形的大小影響並不大。儘管OpenCV推薦訓練樣本的最佳尺寸是20x20,但是在下一步產生樣本描述檔案時可以輕鬆地將其它尺寸縮放到20x20。標定完成後產生的樣本說明檔案info.txt內容舉例如下:

  ?

1 2 3 4 5 rawdata/   (1).bmp 1 118 26 81 72 rawdata/   (10).bmp 2 125 72 48 46 0 70 35 43 rawdata/   (11).bmp 1 105 87 43 42 rawdata/   (12).bmp 2 1 70 34 38 105 87 41 44 ...

 

其中rawdata檔案夾存放了所有待標定的大圖,objectMarker.exe與rawdata檔案夾同級。這個描述檔案的格式已經很接近opencv所要求的了。

2)負樣本的採集:

  所謂負樣本,是指不包含待識別物體的任何圖片,因此你可以將天空、海灘、大山等所有東西都拿來當負樣本。但是,很多時候你這樣做是事倍功半的。大多數模式識別問題都是用在視頻監控領域,攝像機的角度跟高度都相對固定。如果你知道你的項目中攝像機一般都在拍什麼,那負樣本可以非常有針對性地選取,而且可以事半功倍。舉個例子,你現在想做火車站廣場的異常行為檢測,在這個課題中行人檢測是必須要做的。而視訊框架的背景基本都是廣場的地板、建築物等。那你可以在人空曠的時候選擇取一張圖,不同光照不同時段下各取一張圖,然後在這些圖上隨機取映像塊,每個塊20x20,每個塊就是一個負樣本。這幾張圖就能纏上數以千計數以萬計的負樣本。而且針對性強。因為海洋、大山等東西對你的識別一點協助也沒有,還會增加訓練的時間,吃力不討好的事還是少做為好。我寫了一段小程式,功能是根據背景圖片自動隨機產生指定數量指定尺寸的負樣本:

 1 #include "stdafx.h" 2 #include "cv.h" 3 #include "highgui.h" 4 #include <iostream> 5 #include <string> 6  7 using namespace std; 8 using namespace cv; 9 10 //從背景圖片中隨機抽取映像塊,多用於產生負樣本11 #define kImageBlockWidth                40        //映像塊大小12 #define kImageBlockHeight                40        13 #define kLoopTimes                        1000    //期望樣本數14 15 int _tmain(int argc, _TCHAR* argv[])16 {17     int originX = 0, originY = 0;18     int width_limited = 0, height_limited = 0;19     int width = 0, height = 0;20     IplImage *bgImage = cvLoadImage("neg\\bg1.bmp");21     IplImage *blockImage = cvCreateImage(cvSize(kImageBlockWidth, kImageBlockHeight), bgImage->depth, bgImage->nChannels);22     width = bgImage->width;23     height = bgImage->height;24     width_limited = width - kImageBlockWidth;25     height_limited = height - kImageBlockHeight;26     cout<<width_limited<<"   "<<height_limited;27     for (int i = 0; i < kLoopTimes; i++)28     {29         originX = rand() % width_limited;30         originY = rand() % height_limited;31         cvZero(blockImage);32         CvPoint2D32f center_block = cvPoint2D32f(originX + kImageBlockWidth / 2, originY + kImageBlockHeight / 2);33         cvGetRectSubPix(bgImage, blockImage, center_block);34         char saveFileName[100] = {'\0'};35         sprintf(saveFileName, "neg\\(%d).bmp", i + 1);36         cvSaveImage(saveFileName, blockImage);37     }38 39     cvReleaseImage(&bgImage);40     cvReleaseImage(&blockImage);41     system("pause");42     return 0;43 }
負樣本產生代碼

這裡的負樣本尺寸我設定為40x40,是因為在我的應用程式環境下待識別的物體差不多是這個尺寸的。具體可以分析一下你的info.txt檔案。組建檔案後,開cmd.exe cd到該目錄,然後運行“dir /b > neg_sample.dat”,開啟.dat,用editplus替換bmp為bmp 1 0 0 40 40。這樣負樣本說明檔案就產生了。

  對於負樣本,我還有一點要說明:負樣本映像的大小隻要不小於正樣本就可以。opencv在使用你提供的一張負樣本圖片時會自動從其中摳出一塊與正樣本同樣大小的映像作為負樣本,具體的函數可見opencv系統函數cvGetNextFromBackgroundData()。

 

2.產生樣本描述檔案

  樣本描述檔案也即.vec檔案,裡面存放位元據,是為opencv訓練做準備的。只有正樣本需要產生.vec檔案,負樣本不用,負樣本用.dat檔案就夠。在產生描述檔案過程中,我們需要用到opencv內建的opencv_createsamples.exe可執行檔。這個檔案一般存放在opencv安裝目錄的/bin檔案夾下(請善用ctrl+F搜尋)。如果沒有,可以自己編譯一遍也很快。這裡提供懶人版:http://en.pudn.com/downloads204/sourcecode/graph/texture_mapping/detail958471_en.html 這是別人編譯出來的opencv工程,在bin底下可以找到該exe檔案。要注意,該exe依賴於cv200.dll、cxcore200.dll、highgui200.dll這三個動態庫,要保持這四個檔案在同個目錄下。

 

現在我們開始產生描述檔案。建立檔案夾pos、neg分別存放正樣本及負樣本圖片,此處是指沒標定的大圖。

1)修改樣本說明檔案的格式:

在第1步中我們用objectMarker完成標定後會自動產生info.txt,現在我們需要對其格式做一定的微調,通過editplus或者ultraedit將路徑資訊rawdata都替換掉,並命名為sample_pos.dat,也可自訂名字。 ?

1 2 3 4 5 6 (1).bmp 1 118 26 81 72 (10).bmp 2 125 72 48 46 0 70 35 43 (11).bmp 1 105 87 43 42 (12).bmp 2 1 70 34 38 105 87 41 44 (13).bmp 1 102 93 43 41 (14).bmp 1 104 86 45 47

2)使用opencv_createsamples.exe建立樣本描述檔案:

  開啟cmd.exe,cd到opencv_createsamples.exe所在的目錄,執行命令: ?

1 opencv_createsamples.exe <span style= "color: rgb(255, 0, 0);" >-info ./pos/sample_pos.dat</span> -vec ./pos/sample_pos.vec <strong>-num 17</strong> -w 20 -h 20 -show YES

 參數說明:-info,指樣本說明檔案

      -vec,樣本描述檔案的名字及路徑

      -num,總共幾個樣本,要注意,這裡的樣本數是指標定後的20x20的樣本數,而不是大圖的數目,其實就是樣本說明檔案第2列的所有數字累加         和。

      -w -h 指明想讓樣本縮放到什麼尺寸。這裡的奧妙在於你不必另外去處理第1步中被矩形框出的圖片的尺寸,因為這個參數幫你統一縮放。

      -show 是否顯示每個樣本。樣本少可以設為YES,要是樣本多的話最好設為NO,或者不要顯式地設定,因為關視窗會關到你哭

 

done表示建立成功,若建立不成功會報錯,大部分會提示你sample.dat pars error,一般是說明檔案格式有錯,或者num設定過大 ?

1 2 Create training samples from images collection... Done. Created 17 samples

 

總結

總結並延伸以上內容:

1.樣本圖片最好使用灰階圖,且最好能根據實際情況做一定的預先處理

2.樣本選擇的原則是:數量越多越好,盡量高於1000;樣本間差異性越大越好

3.正負樣本比例為1:3最佳,尺寸為20x20最佳

 

That`s all。

==================

附上參考資料,看這些就夠,網上資料太多容易讓人看花眼。

http://blog.csdn.net/think_embed/article/details/9959569

http://www.docin.com/p-80649093.html

http://jingyan.baidu.com/article/4dc40848f50689c8d946f197.html

http://blog.csdn.net/carson2005/article/details/8171571


轉自:http://www.cnblogs.com/wengzilin/p/3845271.html

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.