http://lego.twgg.org/?p=852
最近糊里糊塗的完成了 HOG Detector 對於輪胎偵測的訓練(效果挺優 !!),
都要感謝此網站的達人:http://blog.baifaces.com/baifaces/blog/work/opencv-hog-peopledetector-trainning.html
在此也記錄一下,我實作時的疑難雜症吧!!
實作平台是:Ubuntu 11.04
釋出訓練程式的網站:http://pascal.inrialpes.fr/soft/olt/ (載點) (樣本檔)
樣本檔容量很大,如果只是要單純訓練自己的樣本的話,大可不用抓。
步驟紀錄如下:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
[lego@lego HOG]$ wget http:
//pascal
.inrialpes.fr
/soft/olt/OLTbinaries
.zip
[lego@lego HOG]$ unzip OLTbinaries.zip
[lego@lego HOG]$
cd
OLTbinaries
//
建立樣本資料夾 train 與
test
[lego@lego OLTbinaries]$
mkdir
train
test
//
把你的正樣本 copy 到 train 與
test
目錄中 (pos為你放正樣本圖片的資料夾)
[lego@lego OLTbinaries]$
cp
-r pos train/
[lego@lego OLTbinaries]$
cp
-r pos
test
/
//
把你的負樣本 copy 到 train 與
test
目錄中 (neg為你放負樣本圖片的資料夾)
[lego@lego OLTbinaries]$
cp
-r neg train/
[lego@lego OLTbinaries]$
cp
-r neg
test
/
//
建立正負樣本的 list
[lego@lego OLTbinaries]$
find
train
/pos
> train
/pos
.lst
[lego@lego OLTbinaries]$
find
test
/pos
>
test
/pos
.lst
[lego@lego OLTbinaries]$
find
train
/neg
> train
/neg
.lst
[lego@lego OLTbinaries]$
find
test
/neg
>
test
/neg
.lst
//
做完上述指令後,需要把上面的每一個 lst 檔的第一行 刪掉
//
修改 runall.sh 把其中的 WIDTH 與 HEIGHT 改成你自己的正樣本大小
[lego@lego OLTbinaries]$
vi
runall.sh
WIDTH=64;
export
WIDTH
HEIGHT=128;
export
HEIGHT
//
接下來就開始訓練了 !!! (我訓練的正樣本有 1133 張 size 50 x 50,負樣本有 680 張 size 512x384)
//
跟 AdaBoost 比起來,HOG Detector 的訓練時間算是很快!!
[lego@lego OLTbinaries]$ sh runall.sh
//
等待 runall.sh 跑完後,便可看到 OLTbinaries
/HOG
目錄下,產生了一個 model
file
//
此即為我們訓練好的檔案。
[lego@lego OLTbinaries]$
ls
HOG
/model_4BiSVMLight
.alt
HOG
/model_4BiSVMLight
.alt
|
以上為訓練過程,以下備註一下注意事項:
1. 訓練的正、負圖片可以是 png 或 jpg ( 我用 bmp 時,會出錯 ),還有就是副檔名要小寫。
2. 若要改變訓練完的 model 檔名稱與位置,可在 runall.sh 中修改。
做完訓練,接下來就是測試訓練檔好不好用啦!!
在此它有提供 runonimage.sh 讓我們測試,用法如下:
## 使用前記得先修改 runonimage.sh 內的正樣本圖片長、寬(與你訓練的正樣本長、寬要一樣),不然會出錯。
WIDTH=64; export WIDTH
HEIGHT=128; export HEIGHT
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
|
# runonimage.sh {image name/image directory/list file} {out text file} {out image file/out image dir}
//
總共有三個參數
參數1: 可直接指定預測試的圖片檔名 (ex: photo.jpg ),或者是一個存放圖片清單的檔案
( ex: 存放所有你要測試圖片清單的檔案 image.lst 內容如:
test
/photo1
.jpg )
參數2: 測試過程中,可能會有一些測試結果的資訊, 這些資訊會存入該參數指定的檔案
參數3: 測試完畢後,該程式會將偵測物件的結果資訊,畫在圖片上,因此該參數便是指定這張被繪製偵測結果資訊的圖片的位置,
如果你指定的是圖片檔名,則會以該檔名進行儲存;
如果你指定的是一個目錄,則會以原始測試的檔名,儲存在你指定的目錄中。
//
實際指令下法
# 1 測試單張圖片
[lego@lego OLTbinaries]$ sh runonimage.sh photo.jpg result.txt result.jpg
# 2 測試大量圖片
[lego@lego OLTbinaries]$ sh runonimage.sh image.lst result.txt result_folder/
|
測試的圖片,還是盡量使用 jpg 或 png 且輸出的附檔名一定要是小寫,不然有時候跑起來程式會一直出錯,挺麻煩的。
在此SHOW三張偵測結果圖吧 (效果不賴):
當然 ~ 有時候難免有誤判 。
以後有空再把它整進 Android 手機中試看看好了 !!! 先
为了验证这一想法的正确性和可行性,笔者做了些实验,在Ubuntu10.4 g++4.4.5环境中,步骤如下:
注意事项:
1
|
HardOption=" --poscases 2416 --negcases 1218 "
|
1
2
3
4
|
OutDir=./HOG
InDir=./
OutFile=$OutDir/record
CMDLINE=$OutDir/record
|
1
2
3
4
|
First iteration complete
Hard examples created
Doing second learning
Second iteration complete
|
1
2
|
WIDTH=64; export WIDTH
HEIGHT=128; export HEIGHT
|
有了模型,怎么去做目标检测呢?你可以做以下的试验:
结果:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
/*
* =============================================
*
* Filename: lib-detector.cpp
*
* Description: Code to detect object
*
* Compiler: gcc
*
* Author: Amadeu zou
* URL: www.baifaces.com
*
* =============================================
*/
#include <cv.h>
#include <highgui.h>
#include <string>
#include <iostream>
#include <algorithm>
#include <iterator>
#include <X11/Xlib.h>
#include <Imlib2.h>
#include <lear/interface/windetect.h>// change this path as appropriate.
using namespace std;
std::list<DetectedRegion> detector(char* imgf, WinDetectClassify windetect, LinearClassify* classifier)
{
std::list<DetectedRegion> detections;
// read image
Imlib_Image image = imlib_load_image(imgf);
// if the load was successful
if (image)
{// set the image we loaded as the current context image to work on
imlib_context_set_image(image);
} else {
//std::cerr << "Unable to read image: " << argv[1] << std::endl;
return detections;
}
int width = imlib_image_get_width(),
height = imlib_image_get_height();
typedef unsigned char uchar;
DATA32* data = imlib_image_get_data_for_reading_only();
uchar* imagedata = new uchar[3*width*height*sizeof(uchar)];
for (int j= 0; j< height; ++j)
for (int i= 0; i< width; ++i) {
uchar* pixel = imagedata+(i+j*width)*3;
int argb = data[i+j*width];
pixel[0] = static_cast<uchar>((argb & 0x00FF0000)>>16);
pixel[1] = static_cast<uchar>((argb & 0x0000FF00)>> 8);
pixel[2] = static_cast<uchar>((argb & 0x000000FF) );
}
imlib_free_image();
// now get detections
windetect.test(*classifier, detections, imagedata, width, height);
delete[] imagedata;
return detections;
}
int main(int argc, char** argv) {
if (argc != 4) {
std::cout << "Error" << std::endl;
return 0;
}
char modelpath[256];
strcpy(modelpath,argv[2]);
string model_file(modelpath) ;
// initialize the person detector. All default parameters are set for person detector.
WinDetectClassify windetect;// use default person detector.
RHOGDenseParam desc;
LinearClassify* classifier = NULL;// initialize it to 64x128 person detector.
classifier = new LinearClassify(model_file, 0);
windetect.init(&desc); // initialize the descriptor computation
std::list<DetectedRegion> detections;
detections = detector(argv[1], windetect, classifier);
//draw region in image
IplImage* img = cvLoadImage(argv[1],1);
for(list<DetectedRegion>::iterator itor=detections.begin();itor!=detections.end();++itor)
{
cvRectangle(img,cvPoint(itor->x,itor->y),cvPoint(itor->x+itor->width,itor->y+itor->height),cvScalar(0,0,255),2);
}
cvSaveImage(argv[3],img);
cvReleaseImage(&img);
//print detections
std::copy(detections.begin(), detections.end(), std::ostream_iterator<DetectedRegion>(std::cout, "\n"));
return 0;
}
|
编译:
1
|
g++ `pkg-config --cflags --libs opencv` -O3 -o lib-detector lib-detector.cpp -I. -I/usr/include -L. -lcmdline -lcvip -lclassifier -llearutil -lboost_filesystem-gcc -lblitz -L/usr/lib -lImlib2 -lfreetype -lz -L/usr/X11R6/lib -lX11 -lXext -ldl -lm
|
结果:
1
2
3
4
|
amadeuzou@ubuntu:~/Projects/opencv/OLTbinaries/lib$ ./lib-detector person-1.jpg model_4BiSVMLight.alt result.jpg
298 215 145 290 2.2674 1.10256009e-01
13 9 237 475 3.71704 1.31164089e-01
234 -7 230 460 3.59693 1.35627717e-01
|