0pencv 分類器 haartraining生成.xml文件過程

1.準備正負樣本:

     在上一講http://www.cnblogs.com/tornadomeet/archive/2012/03/27/2420088.html 中,我們已經收集到了訓練所用的正樣本。下面就開始收集負樣本了,負樣本要求是:不能包含人臉,且圖片大小也不需要歸一化到正樣本尺寸,只需比正樣本尺寸大或者相等即可。建議負樣本用灰度圖,加快訓練速度,且負樣本一定不能重複,要增大負樣本的差異性。

     這裏我採用的負樣本是用的是weizmann團隊http://www.wisdom.weizmann.ac.il/~vision/Seg_Evaluation_DB/dl.html 網站上的圖像分割數據庫,裏面有灰色圖和彩色圖,這裏當然選取灰度圖了。

     總共用了200幅圖片,大小大約在300*200像素,截圖如下所示:

     可以看出這些200多張圖片基本都沒有人臉,所以說應該是可以的。

     正負樣本的圖片準備好了,下面就開始製作正負樣本的描述文件了。

     首先建立好文件夾,把圖片拷貝好,如下所示:

    

     Pos_image中放入的是正樣本,neg_image放入的是負樣本,test_image放入的是測試樣本。並將後面要用到的2個工具.exe文件也拷貝過來(在opencv的安裝目錄C:\Program Files\opencv2.3.1\build\common\x86下)。

2.生成正負樣本描述文件:

     建立正樣本的描述文件:

     打開cmd窗口,進入上圖所在pos_img文件夾內,可以看到此文件夾圖片顯示如下:

     

     使用命令dir /b >pos_image.txt。如圖所示

     

    且用editplus打開該文件,刪除最後一行,最後將名字歸一化如下所示:

     其中的pos_image/是相對路徑名,後面緊接着的是文件名,1代表一個文件,0 0 24 24表示這個文件的2個頂點位置座標。保存退出即ok!

負樣本的描述文件類似,只是不需要考慮其大小位置。

     也是進入neg_imgae後在cmd內使用命令dir /b >neg_image.txt,如圖所示:

     

     同樣刪除最後一行文字,且將文件相對路徑加入如下所示:

  

 

     至此,訓練數據準備完備了。

3.創建vec文件:

     在創建vec文件時,需要把pos_image.txt和neg_image.txt兩個樣本描述文件剪切到上一目錄,如圖所示:

     然後利用opencv_createsamples.exe應用程序在該目錄下使用如下cmd命令:

    

     其中的-vec是指定後面輸出vec文件的文件名,-info指定正樣本描述文件,-bg指定負樣本描述文件,-w和-h分別指正樣本的寬和高,-num表示正樣本的個數。執行完該命令後就會在當前目錄下生產一個pos.vec文件了。

4.使用opencv_文件進行訓練

   也可參照http://blog.csdn.net/wuxiaoyao12/article/details/39227189

     首先在當前目錄下新建一個xml文件夾用於存放生成的.xml文件。

     在當前目錄使用cmd命令:

     Opcnv_haartraining.exe –data xml –vec pos.vec –bg neg_image.txt –nsplits 1 –sym –w 24 –h 24 –mode all –mem 1280

截圖如下:

     

     其中-data爲輸出xml中間文件的位置,-sym表示訓練的目標爲垂直對稱,-nsplits 1表示使用簡單的stump classfier分類。-mem 1280 表示允許使用計算機的1280M內存,-mode all 表示使用haar特徵集的種類既有垂直的,又有45度角旋轉的。

     因爲數據量不是很多,不到半個鐘頭就訓練好了。在當前目錄下生產了一個xml.xml文件,將其重名名爲face_test.xml。

5.實驗結果:

     利用上面訓練出來的face_test.xml文件來檢測下人臉,首先來一張比較正面的人臉圖,用奧巴馬的,檢測結果如下:

     

     爲了看看是否不是特別正的,且有背景干擾的結果,用了lena的圖,檢測結果如下:

     

 

 

     上面說明其效果還是不錯的。其測試源碼和前面的博客http://www.cnblogs.com/tornadomeet/archive/2012/03/22/2411318.html的代碼類似,刪減了人眼檢測的代碼而已,源碼如下:

複製代碼
 1 // face_detect.cpp : 定義控制檯應用程序的入口點。
 2 //
 3 #include "stdafx.h"
 4 
 5 #include "opencv2/objdetect/objdetect.hpp"
 6 #include "opencv2/highgui/highgui.hpp"
 7 #include "opencv2/imgproc/imgproc.hpp"
 8 #include "opencv2/ml/ml.hpp"
 9 
10 #include <iostream>
11 #include <stdio.h>
12 
13 using namespace std;
14 using namespace cv;
15 
16 void detectAndDraw( Mat& img,
17                    CascadeClassifier& cascade, 
18                    double scale);
19 
20 String cascadeName = "./face_test.xml";//人臉的訓練數據
21 
22 int main( int argc, const char** argv )
23 {
24     Mat image;
25     CascadeClassifier cascade, nestedCascade;//創建級聯分類器對象
26     double scale = 1.3;
27 //    image = imread("obama_gray.bmp",1);
28     image = imread("lena_gray.jpg",1);
29     namedWindow( "result", 1 );//opencv2.0以後用namedWindow函數會自動銷燬窗口
30 
31     if( !cascade.load( cascadeName ) )//從指定的文件目錄中加載級聯分類器
32     {
33          cerr << "ERROR: Could not load classifier cascade" << endl;
34          return 0;
35     }
36 
37     if( !image.empty() )//讀取圖片數據不能爲空
38     {
39         detectAndDraw( image, cascade, scale );
40         waitKey(0);
41     }
42 
43     return 0;
44 }
45 
46 void detectAndDraw( Mat& img,
47                    CascadeClassifier& cascade, 
48                    double scale)
49 {
50     int i = 0;
51     double t = 0;
52     vector<Rect> faces;
53     const static Scalar colors[] =  { CV_RGB(0,0,255),
54         CV_RGB(0,128,255),
55         CV_RGB(0,255,255),
56         CV_RGB(0,255,0),
57         CV_RGB(255,128,0),
58         CV_RGB(255,255,0),
59         CV_RGB(255,0,0),
60         CV_RGB(255,0,255)} ;//用不同的顏色表示不同的人臉
61 
62     Mat gray, smallImg( cvRound (img.rows/scale), cvRound(img.cols/scale), CV_8UC1 );//將圖片縮小,加快檢測速度
63 
64     cvtColor( img, gray, CV_BGR2GRAY );//因爲用的是類haar特徵,所以都是基於灰度圖像的,這裏要轉換成灰度圖像
65     resize( gray, smallImg, smallImg.size(), 0, 0, INTER_LINEAR );//將尺寸縮小到1/scale,用線性插值
66     equalizeHist( smallImg, smallImg );//直方圖均衡
67 
68     t = (double)cvGetTickCount();//用來計算算法執行時間
69 
70 //檢測人臉
71 //detectMultiScale函數中smallImg表示的是要檢測的輸入圖像爲smallImg,faces表示檢測到的人臉目標序列,1.1表示
72 //每次圖像尺寸減小的比例爲1.1,2表示每一個候選矩形需要記錄2個鄰居,CV_HAAR_SCALE_IMAGE表示使用haar特徵,Size(30, 30)
73 //爲目標的最小最大尺寸
74     cascade.detectMultiScale( smallImg, faces,
75         1.1, 2, 0
76         //|CV_HAAR_FIND_BIGGEST_OBJECT
77 //|CV_HAAR_DO_ROUGH_SEARCH
78         |CV_HAAR_SCALE_IMAGE
79         ,
80         Size(30, 30) );
81 
82     t = (double)cvGetTickCount() - t;//相減爲算法執行的時間
83     printf( "detection time = %g ms\n", t/((double)cvGetTickFrequency()*1000.) );
84     for( vector<Rect>::const_iterator r = faces.begin(); r != faces.end(); r++, i++ )
85     {
86         Mat smallImgROI;
87         vector<Rect> nestedObjects;
88         Point center;
89         Scalar color = colors[i%8];
90         int radius;
91         center.x = cvRound((r->x + r->width*0.5)*scale);//還原成原來的大小
92         center.y = cvRound((r->y + r->height*0.5)*scale);
93         radius = cvRound((r->width + r->height)*0.25*scale);
94         circle( img, center, radius, color, 3, 8, 0 );
95         smallImgROI = smallImg(*r);
96     }
97     cv::imshow( "result", img );
98 }
複製代碼

 

 

6.參考文獻:

1. http://hi.baidu.com/zdd007007/blog/item/b2e7f026eec9e23f8644f959.html 的博客。

2. http://blog.csdn.net/guxj821/article/details/6341239 網友周明才的博客。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章