训练自己haar-like特征分类器并识别物体(1)
本系列文章旨在學(xué)習(xí)如何在opencv中基于haar-like特征訓(xùn)練自己的分類器,并且用該分類器用于模式識(shí)別。該過程大致可以分為一下幾個(gè)大步驟:
1.準(zhǔn)備訓(xùn)練樣本圖片,包括正例及反例樣本
2.生成樣本描述文件
3.訓(xùn)練樣本
4.目標(biāo)識(shí)別
=================
本文主要對(duì)步驟1、步驟2進(jìn)行說明。
1.準(zhǔn)備訓(xùn)練樣本圖片,包括正例及反例樣本
1)正樣本的采集:
所謂正樣本,是指只包含待識(shí)別的物體的圖片,一般是一些局部的圖片,且最好能轉(zhuǎn)化為灰度圖。比如,若你想識(shí)別人臉,則正樣本應(yīng)盡可能只包含人臉,可以留一點(diǎn)周邊的背景但不要過多。在正樣本的采集上,我們有兩種圖形標(biāo)定工具可以使用:(1)opencv的imageClipper (2)objectMarker。這兩個(gè)工具都支持傻瓜式地對(duì)圖片中的物體進(jìn)行矩形標(biāo)定,可以自動(dòng)生成樣本說明文件,自動(dòng)逐幀讀取文件夾內(nèi)的下一幀。我用的是objectMarker。如果你找不到這個(gè)軟件,可以留下郵箱,我發(fā)給你。
在標(biāo)定的時(shí)候盡量保持長(zhǎng)寬比例一致,也就是盡量用接近正方形的矩形去標(biāo)定待識(shí)別的物體,至于正方形的大小影響并不大。盡管OpenCV推薦訓(xùn)練樣本的最佳尺寸是20x20,但是在下一步生成樣本描述文件時(shí)可以輕松地將其它尺寸縮放到20x20。標(biāo)定完成后生成的樣本說明文件info.txt內(nèi)容舉例如下:
?
| 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文件夾存放了所有待標(biāo)定的大圖,objectMarker.exe與rawdata文件夾同級(jí)。這個(gè)描述文件的格式已經(jīng)很接近opencv所要求的了。
2)負(fù)樣本的采集:
所謂負(fù)樣本,是指不包含待識(shí)別物體的任何圖片,因此你可以將天空、海灘、大山等所有東西都拿來當(dāng)負(fù)樣本。但是,很多時(shí)候你這樣做是事倍功半的。大多數(shù)模式識(shí)別問題都是用在視頻監(jiān)控領(lǐng)域,攝像機(jī)的角度跟高度都相對(duì)固定。如果你知道你的項(xiàng)目中攝像機(jī)一般都在拍什么,那負(fù)樣本可以非常有針對(duì)性地選取,而且可以事半功倍。舉個(gè)例子,你現(xiàn)在想做火車站廣場(chǎng)的異常行為檢測(cè),在這個(gè)課題中行人檢測(cè)是必須要做的。而視頻幀的背景基本都是廣場(chǎng)的地板、建筑物等。那你可以在人空曠的時(shí)候選擇取一張圖,不同光照不同時(shí)段下各取一張圖,然后在這些圖上隨機(jī)取圖像塊,每個(gè)塊20x20,每個(gè)塊就是一個(gè)負(fù)樣本。這幾張圖就能纏上數(shù)以千計(jì)數(shù)以萬計(jì)的負(fù)樣本!而且針對(duì)性強(qiáng)。因?yàn)楹Q蟆⒋笊降葨|西對(duì)你的識(shí)別一點(diǎn)幫助也沒有,還會(huì)增加訓(xùn)練的時(shí)間,吃力不討好的事還是少做為好。我寫了一段小程序,功能是根據(jù)背景圖片自動(dòng)隨機(jī)生成指定數(shù)量指定尺寸的負(fù)樣本:
#include "stdafx.h" #include "cv.h" #include "highgui.h" #include <iostream> #include <string>using namespace std; using namespace cv;//從背景圖片中隨機(jī)抽取圖像塊,多用于生成負(fù)樣本 #define kImageBlockWidth 40 //圖像塊大小 #define kImageBlockHeight 40 #define kLoopTimes 1000 //期望樣本數(shù)int _tmain(int argc, _TCHAR* argv[]) {int originX = 0, originY = 0;int width_limited = 0, height_limited = 0;int width = 0, height = 0;IplImage *bgImage = cvLoadImage("neg\\bg1.bmp");IplImage *blockImage = cvCreateImage(cvSize(kImageBlockWidth, kImageBlockHeight), bgImage->depth, bgImage->nChannels);width = bgImage->width;height = bgImage->height;width_limited = width - kImageBlockWidth;height_limited = height - kImageBlockHeight;cout<<width_limited<<" "<<height_limited;for (int i = 0; i < kLoopTimes; i++){originX = rand() % width_limited;originY = rand() % height_limited;cvZero(blockImage);CvPoint2D32f center_block = cvPoint2D32f(originX + kImageBlockWidth / 2, originY + kImageBlockHeight / 2);cvGetRectSubPix(bgImage, blockImage, center_block);char saveFileName[100] = {'\0'};sprintf(saveFileName, "neg\\(%d).bmp", i + 1);cvSaveImage(saveFileName, blockImage);}cvReleaseImage(&bgImage);cvReleaseImage(&blockImage);system("pause");return 0; }負(fù)樣本生成代碼
這里的負(fù)樣本尺寸我設(shè)定為40x40,是因?yàn)樵谖业膽?yīng)用環(huán)境下待識(shí)別的物體差不多是這個(gè)尺寸的。具體可以分析一下你的info.txt文件。生成文件后,開cmd.exe cd到該目錄,然后運(yùn)行“dir /b > neg_sample.dat”,打開.dat,用editplus替換bmp為bmp 1 0 0 40 40。這樣負(fù)樣本說明文件就產(chǎn)生了。
對(duì)于負(fù)樣本,我還有一點(diǎn)要說明:負(fù)樣本圖像的大小只要不小于正樣本就可以。opencv在使用你提供的一張負(fù)樣本圖片時(shí)會(huì)自動(dòng)從其中摳出一塊與正樣本同樣大小的圖像作為負(fù)樣本,具體的函數(shù)可見opencv系統(tǒng)函數(shù)cvGetNextFromBackgroundData()。
?
2.生成樣本描述文件
樣本描述文件也即.vec文件,里面存放二進(jìn)制數(shù)據(jù),是為opencv訓(xùn)練做準(zhǔn)備的。只有正樣本需要生成.vec文件,負(fù)樣本不用,負(fù)樣本用.dat文件就夠。在生成描述文件過程中,我們需要用到opencv自帶的opencv_createsamples.exe可執(zhí)行文件。這個(gè)文件一般存放在opencv安裝目錄的/bin文件夾下(請(qǐng)善用ctrl+F搜索)。如果沒有,可以自己編譯一遍也很快。這里提供懶人版:http://en.pudn.com/downloads204/sourcecode/graph/texture_mapping/detail958471_en.html?這是別人編譯出來的opencv工程,在bin底下可以找到該exe文件。要注意,該exe依賴于cv200.dll、cxcore200.dll、highgui200.dll這三個(gè)動(dòng)態(tài)庫,要保持這四個(gè)文件在同個(gè)目錄下。
?
現(xiàn)在我們開始生成描述文件。新建文件夾pos、neg分別存放正樣本及負(fù)樣本圖片,此處是指沒標(biāo)定的大圖。
1)修改樣本說明文件的格式:
在第1步中我們用objectMarker完成標(biāo)定后會(huì)自動(dòng)生成info.txt,現(xiàn)在我們需要對(duì)其格式做一定的微調(diào),通過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創(chuàng)建樣本描述文件:
打開cmd.exe,cd到opencv_createsamples.exe所在的目錄,執(zhí)行命令:
| 1 | opencv_createsamples.exe <span style="color: #ff0000;">-info ./pos/sample_pos.dat</span> -vec ./pos/sample_pos.vec <strong>-num 17</strong> -w 20 -h 20 -show YES |
參數(shù)說明:-info,指樣本說明文件
-vec,樣本描述文件的名字及路徑
-num,總共幾個(gè)樣本,要注意,這里的樣本數(shù)是指標(biāo)定后的20x20的樣本數(shù),而不是大圖的數(shù)目,其實(shí)就是樣本說明文件第2列的所有數(shù)字累加 和。
-w -h 指明想讓樣本縮放到什么尺寸。這里的奧妙在于你不必另外去處理第1步中被矩形框出的圖片的尺寸,因?yàn)檫@個(gè)參數(shù)幫你統(tǒng)一縮放!
-show 是否顯示每個(gè)樣本。樣本少可以設(shè)為YES,要是樣本多的話最好設(shè)為NO,或者不要顯式地設(shè)置,因?yàn)殛P(guān)窗口會(huì)關(guān)到你哭
?
done表示創(chuàng)建成功,若創(chuàng)建不成功會(huì)報(bào)錯(cuò),大部分會(huì)提示你sample.dat pars error,一般是說明文件格式有錯(cuò),或者num設(shè)置過大
| 1 2 | Create training samples?from?images collection... Done. Created 17 samples |
?
總結(jié)
總結(jié)并延伸以上內(nèi)容:
1.樣本圖片最好使用灰度圖,且最好能根據(jù)實(shí)際情況做一定的預(yù)處理
2.樣本選擇的原則是:數(shù)量越多越好,盡量高于1000;樣本間差異性越大越好
3.正負(fù)樣本比例為1:3最佳,尺寸為20x20最佳
?
That`s all。
==================
附上參考資料,看這些就夠,網(wǎng)上資料太多容易讓人看花眼!
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
?
objectMarker下載鏈接【20151218更新】
http://download.csdn.net/download/lglgaigogo/1197957
from:?http://www.cnblogs.com/wengzilin/p/3845271.html
總結(jié)
以上是生活随笔為你收集整理的训练自己haar-like特征分类器并识别物体(1)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何写一个完善的c++异常处理类
- 下一篇: Github系列之二:开源 一行代码实现