1. 程式人生 > >Opencv 特徵訓練分類器

Opencv 特徵訓練分類器

一、基礎知識準備

首先,opencv目前僅支援三種特徵的訓練檢測, HAAR、LBP、HOG,選擇哪個特徵就去補充哪個吧。opencv的這個訓練演算法是基於adaboost而來的,所以需要先對adaboost進行基礎知識補充啊,網上一大堆資料,同志們速度去查閱。我的資源裡也有,大家去下載吧,這些我想都不是大家能直接拿來用的,我下面將直接手把手告訴大家訓練怎麼操作,以及要注意哪些細節。

二、關於正樣本的準備

1、採集正樣本圖片

因為正樣本最後需要大小歸一化,所以我在採集樣本的時候就直接把它從原圖裡摳出來了,方便後面縮放嘛,而不是隻儲存它的框個數和框位置資訊(框個數、框位置資訊看下一步解釋),在裁剪的過程中儘量保持樣本的長寬比例一致。比如我最後要歸一化成20 X 20,在裁剪樣本的時候,我都是20X20或者21X21、22X22等等,最大我也沒有超過30X30(不超過跟我的自身用途有關,對於人臉檢測這種要保證縮放不變性的樣本,肯定就可以超過啦),我資源裡也給出可以直接用的裁剪樣本程式。

(這裡我說錯了,根據createsamples.cpp ,我們不需要提前進行縮放操作,它在第3步變成vec時就包含了縮放工作.如果我們是用objectMaker標記樣本,程式同時生成的關於每一幅圖的samplesInfo資訊,直接給第三步用即可。當然,你提前縮放了也沒關係,按照第2步操作即可)

2、獲取正樣本路徑列表

在你的圖片資料夾裡,編寫一個bat程式(get route.bat,bat是避免每次都需要去dos框輸入,那裡又不能複製又不能貼上!),如下所示:


執行bat檔案,就會生成如下dat檔案:


把這個dat檔案中的所有非圖片的路徑都刪掉,比如上圖的頭兩行,再將bmp 替換成 bmp 1 0 0 20 20,如下:


(1代表個數,後四個分別對應 left top width height,如果我們之前不是把樣本裁剪下來的,那麼你的這個dat可能就長成這樣1. bmp 3 1 3 24 24 26 28 25 25 60 80 26 26,1.bmp是完全的原圖啊,你之前的樣本就是從這張圖上扣下來的)

3、獲取供訓練的vec檔案

這裡,我們得利用opencv裡的一個程式叫opencv_createsamples.exe,可以把它拷貝出來。針對它的命令輸入也是寫成bat檔案啦,因為cascade訓練的時候用的是vec。如下:


執行bat,就在我們得pos資料夾裡生成了如下vec檔案:

就此有關正樣本的東西準備結束。

(vec中其實就是儲存的每一個sample圖,並且已經統一w、h大小了,如果你想看所有的sample,也可以通過呼叫opencv_createsamples.exe,使用操作,見附)

三、關於負樣本的準備

這個特別簡單,直接拿原始圖,不需要裁剪摳圖(不裁剪還能保證樣本的多樣性),也不需要儲存框(網上說只要保證比正樣本大小大哈,大家就保證吧),只要把路徑儲存下來。同正樣本類似,步驟圖如下:



至此有關負樣本的也準備完成。

四、開始訓練吧

這裡我們用opencv_traincascade.exe(opencv_haartraining.exe的用法跟這個很相似,具體需要輸入哪些引數去看opencv的原始碼吧,網上資料也有很多,主要是opencv_traincascade.exe比opencv_haartraining.exe包含更多的特徵,功能齊全些啊),直接上圖:


命令輸入也直接用bat檔案,請務必保證好大小寫一致,不然不予識別引數。小白兔,跑起來~~~


這是程式識別到的引數,沒有錯把,如果你哪個字母打錯了,你就會發現這些引數會跟你預設的不一樣啊,所以大家一定要看清楚了~~~~

跑啊跑啊跑啊跑,如下:


這一級的強訓練器達到你預設的比例以後就跑去訓練下一級了,同志們那個HR比例不要設定太高,不然會需要好多樣本,然後stagenum不要設定太小啊,不然到時候拿去檢測速度會很慢。

等這個bat跑結束,我的xml檔案也生成了。如下:


其實這個訓練可以中途停止的,因為下次開啟時它會讀取這些xml檔案,接著進行上次未完成的訓練。哈哈~~~~好人性化啊!

訓練結束,我要到了我的cascade.xml檔案,現在我要拿它去做檢測了啊!呼呼~~~~

五、開始檢測吧

opencv有個opencv_performance.exe程式用於檢測,但是它只能用在用opencv_haartraining.exe來用的,所以我這裡是針對一些列圖片進行檢測的,檢測程式碼如下:

[cpp] view plain copy print?在CODE上檢視程式碼片派生到我的程式碼片
  1. #include <windows.h>
  2. #include <mmsystem.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include “wininet.h”
  6. #include <direct.h>
  7. #include <string.h>
  8. #include <list>
  9. #pragma comment(lib,”Wininet.lib”)
  10. #include “opencv2/objdetect/objdetect.hpp”
  11. #include “opencv2/highgui/highgui.hpp”
  12. #include “opencv2/imgproc/imgproc.hpp”
  13. #include “opencv2/ml/ml.hpp”
  14. #include <iostream>
  15. #include <stdio.h>
  16. usingnamespace std;  
  17. usingnamespace cv;  
  18. String cascadeName = ”./cascade.xml”;//訓練資料
  19. struct PathElem{  
  20.     TCHAR   SrcImgPath[MAX_PATH*2];  
  21.     TCHAR   RstImgPath[MAX_PATH*2];  
  22. };  
  23. int FindImgs(char  pSrcImgPath, char  pRstImgPath, std::list<PathElem> &ImgList);  
  24. int main( )  
  25. {  
  26.     CascadeClassifier cascade;//建立級聯分類器物件
  27.     std::list<PathElem> ImgList;   
  28.     std::list<PathElem>::iterator pImgListTemp;   
  29.     vector<Rect> rects;  
  30.     vector<Rect>::const_iterator pRect;  
  31.     double scale = 1.;  
  32.     Mat image;  
  33.     double t;  
  34.     if( !cascade.load( cascadeName ) )//從指定的檔案目錄中載入級聯分類器
  35.     {  
  36.         cerr << ”ERROR: Could not load classifier cascade” << endl;  
  37.         return 0;  
  38.     }  
  39.     int nFlag = FindImgs(“H:/SrcPic/”,“H:/RstPic/”, ImgList);         
  40.     if(nFlag != 0)     
  41.     {  
  42.         cout<<”Read Image  error !  Input 0 to exit \n”;  
  43.         exit(0);  
  44.     }  
  45.     pImgListTemp = ImgList.begin();  
  46.     for(int iik = 1; iik <= ImgList.size(); iik++,pImgListTemp++)  
  47.     {  
  48.         image = imread(pImgListTemp->SrcImgPath);      
  49.         if( !image.empty() )//讀取圖片資料不能為空
  50.         {  
  51.             Mat gray, smallImg( cvRound (image.rows/scale), cvRound(image.cols/scale), CV_8UC1 );//將圖片縮小,加快檢測速度
  52.             cvtColor( image, gray, CV_BGR2GRAY );//因為用的是類haar特徵,所以都是基於灰度影象的,這裡要轉換成灰度影象
  53.             resize( gray, smallImg, smallImg.size(), 0, 0, INTER_LINEAR );//將尺寸縮小到1/scale,用線性插值
  54.             equalizeHist( smallImg, smallImg );//直方圖均衡
  55.             //detectMultiScale函式中smallImg表示的是要檢測的輸入影象為smallImg,rects表示檢測到的目標序列,1.1表示
  56.             //每次影象尺寸減小的比例為1.1,2表示每一個目標至少要被檢測到3次才算是真的目標(因為周圍的畫素和不同的視窗大
  57.             //小都可以檢測到目標),CV_HAAR_SCALE_IMAGE表示不是縮放分類器來檢測,而是縮放影象,Size(30, 30)為目標的
  58.             //最小最大尺寸
  59.             rects.clear();  
  60.             printf( ”begin…\n”);  
  61.             t = (double)cvGetTickCount();//用來計算演算法執行時間
  62.             cascade.detectMultiScale(smallImg,rects,1.1,2,0,Size(20,20),Size(30,30));  
  63.             //|CV_HAAR_FIND_BIGGEST_OBJECT//|CV_HAAR_DO_ROUGH_SEARCH|CV_HAAR_SCALE_IMAGE,
  64.             t = (double)cvGetTickCount() - t;  
  65.             printf( ”detection time = %g ms\n\n”, t/((double)cvGetTickFrequency()1000.) );  
  66.             for(pRect = rects.begin(); pRect != rects.end(); pRect++)  
  67.             {  
  68.                 rectangle(image,cvPoint(pRect->x,pRect->y),cvPoint(pRect->x+pRect->width,pRect->y+pRect->height),cvScalar(0,255,0));  
  69.             }  
  70.             imwrite(pImgListTemp->RstImgPath,image);  
  71.         }  
  72.     }  
  73.     return 0;  
  74. }  
  75. int FindImgs(char  pSrcImgPath, char  pRstImgPath, std::list<PathElem> &ImgList)  
  76. {  
  77.     //源圖片存在的目錄
  78.     TCHAR   szFileT1[MAX_PATH*2];  
  79.     lstrcpy(szFileT1,TEXT(pSrcImgPath));     
  80.     lstrcat(szFileT1, TEXT(”.*”));  
  81.     //結果圖片存放的目錄
  82.     TCHAR   RstAddr[MAX_PATH*2];   
  83.     lstrcpy(RstAddr,TEXT(pRstImgPath));  
  84.     _mkdir(RstAddr);   //建立資料夾
  85.     WIN32_FIND_DATA   wfd;    
  86.     HANDLE   hFind   =   FindFirstFile(szFileT1, &wfd);   
  87.     PathElem stPathElemTemp;  
  88.     if(hFind != INVALID_HANDLE_VALUE)     
  89.     {  
  90.         do
  91.         {   
  92.             if(wfd.cFileName[0] == TEXT(‘.’))   
  93.                 continue;  
  94.             if(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY || strcmp(“Thumbs.db”, TEXT(wfd.cFileName)) == 0)   
  95.             {   
  96.                 ;  
  97.             }    
  98.             else
  99.             {   
  100.                 TCHAR   SrcImgPath[MAX_PATH*2];  
  101.                 lstrcpy(SrcImgPath, pSrcImgPath);   
  102.                 lstrcat(SrcImgPath, TEXT(wfd.cFileName));  
  103.                 lstrcpy(stPathElemTemp.SrcImgPath, SrcImgPath);   
  104.                 TCHAR   AdressTemp[MAX_PATH*2];  
  105.                 lstrcpy(AdressTemp,pRstImgPath);   
  106.                 //lstrcat(AdressTemp, TEXT(“/”));  
  107.                 lstrcat(AdressTemp, TEXT(wfd.cFileName));    
  108.                 lstrcpy(stPathElemTemp.RstImgPath, AdressTemp);   
  109.                 ImgList.push_back(stPathElemTemp);  
  110.             }  
  111.         }while(FindNextFile(hFind, &wfd));  
  112.     }  
  113.     else
  114.     {  
  115.         return -1;  
  116.     }  
  117.     return 0;  
  118. }  
#include <windows.h>
#include <mmsystem.h> #include <stdio.h> #include <stdlib.h> #include "wininet.h" #include <direct.h> #include <string.h> #include <list> #pragma comment(lib,"Wininet.lib") #include "opencv2/objdetect/objdetect.hpp" #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/ml/ml.hpp" #include <iostream> #include <stdio.h> using namespace std; using namespace cv; String cascadeName = "./cascade.xml";//訓練資料 struct PathElem{ TCHAR SrcImgPath[MAX_PATH*2]; TCHAR RstImgPath[MAX_PATH*2]; }; int FindImgs(char * pSrcImgPath, char * pRstImgPath, std::list<PathElem> &ImgList); int main( ) { CascadeClassifier cascade;//建立級聯分類器物件 std::list<PathElem> ImgList; std::list<PathElem>::iterator pImgListTemp; vector<Rect> rects; vector<Rect>::const_iterator pRect; double scale = 1.; Mat image; double t; if( !cascade.load( cascadeName ) )//從指定的檔案目錄中載入級聯分類器 { cerr << "ERROR: Could not load classifier cascade" << endl; return 0; } int nFlag = FindImgs("H:/SrcPic/","H:/RstPic/", ImgList); if(nFlag != 0) { cout<<"Read Image error ! Input 0 to exit \n"; exit(0); } pImgListTemp = ImgList.begin(); for(int iik = 1; iik <= ImgList.size(); iik++,pImgListTemp++) { image = imread(pImgListTemp->SrcImgPath); if( !image.empty() )//讀取圖片資料不能為空 { Mat gray, smallImg( cvRound (image.rows/scale), cvRound(image.cols/scale), CV_8UC1 );//將圖片縮小,加快檢測速度 cvtColor( image, gray, CV_BGR2GRAY );//因為用的是類haar特徵,所以都是基於灰度影象的,這裡要轉換成灰度影象 resize( gray, smallImg, smallImg.size(), 0, 0, INTER_LINEAR );//將尺寸縮小到1/scale,用線性插值 equalizeHist( smallImg, smallImg );//直方圖均衡 //detectMultiScale函式中smallImg表示的是要檢測的輸入影象為smallImg,rects表示檢測到的目標序列,1.1表示 //每次影象尺寸減小的比例為1.1,2表示每一個目標至少要被檢測到3次才算是真的目標(因為周圍的畫素和不同的視窗大 //小都可以檢測到目標),CV_HAAR_SCALE_IMAGE表示不是縮放分類器來檢測,而是縮放影象,Size(30, 30)為目標的 //最小最大尺寸 rects.clear(); printf( "begin...\n"); t = (double)cvGetTickCount();//用來計算演算法執行時間 cascade.detectMultiScale(smallImg,rects,1.1,2,0,Size(20,20),Size(30,30)); //|CV_HAAR_FIND_BIGGEST_OBJECT//|CV_HAAR_DO_ROUGH_SEARCH|CV_HAAR_SCALE_IMAGE, t = (double)cvGetTickCount() - t; printf( "detection time = %g ms\n\n", t/((double)cvGetTickFrequency()*1000.) ); for(pRect = rects.begin(); pRect != rects.end(); pRect++) { rectangle(image,cvPoint(pRect->x,pRect->y),cvPoint(pRect->x+pRect->width,pRect->y+pRect->height),cvScalar(0,255,0)); } imwrite(pImgListTemp->RstImgPath,image); } } return 0; } int FindImgs(char * pSrcImgPath, char * pRstImgPath, std::list<PathElem> &ImgList) { //源圖片存在的目錄 TCHAR szFileT1[MAX_PATH*2]; lstrcpy(szFileT1,TEXT(pSrcImgPath)); lstrcat(szFileT1, TEXT("*.*")); //結果圖片存放的目錄 TCHAR RstAddr[MAX_PATH*2]; lstrcpy(RstAddr,TEXT(pRstImgPath)); _mkdir(RstAddr); //建立資料夾 WIN32_FIND_DATA wfd; HANDLE hFind = FindFirstFile(szFileT1, &wfd); PathElem stPathElemTemp; if(hFind != INVALID_HANDLE_VALUE) { do { if(wfd.cFileName[0] == TEXT('.')) continue; if(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY || strcmp("Thumbs.db", TEXT(wfd.cFileName)) == 0) { ; } else { TCHAR SrcImgPath[MAX_PATH*2]; lstrcpy(SrcImgPath, pSrcImgPath); lstrcat(SrcImgPath, TEXT(wfd.cFileName)); lstrcpy(stPathElemTemp.SrcImgPath, SrcImgPath); TCHAR AdressTemp[MAX_PATH*2]; lstrcpy(AdressTemp,pRstImgPath); //lstrcat(AdressTemp, TEXT("/")); lstrcat(AdressTemp, TEXT(wfd.cFileName)); lstrcpy(stPathElemTemp.RstImgPath, AdressTemp); ImgList.push_back(stPathElemTemp); } }while(FindNextFile(hFind, &wfd)); } else { return -1; } return 0; }

自己看看自己的檢測結果咯。效果不好的改進樣本,調整訓練引數吧~~~嘎嘎

我覺得我寫的夠白痴,很方便大家直接拿來用。其中一些細節,大家自己琢磨吧~88

附:

1、opencv_createsamples.exe的引數

(createsamples.cpp)

[cpp] view plain copy print?在CODE上檢視程式碼片派生到我的程式碼片
  1. ”  [-info <collection_file_name>]\n”
  2. ”  [-img <image_file_name>]\n”
  3. ”  [-vec <vec_file_name>]\n”
  4. ”  [-bg <background_file_name>]\n  [-num <number_of_samples = %d>]\n”
  5. ”  [-bgcolor <background_color = %d>]\n”
  6. ”  [-inv] [-randinv] [-bgthresh <background_color_threshold = %d>]\n”
  7. ”  [-maxidev <max_intensity_deviation = %d>]\n”
  8. ”  [-maxxangle <max_x_rotation_angle = %f>]\n”
  9. ”  [-maxyangle <max_y_rotation_angle = %f>]\n”
  10. ”  [-maxzangle <max_z_rotation_angle = %f>]\n”
  11. ”  [-show [<scale = %f>]]\n”
  12. ”  [-w <sample_width = %d>]\n  [-h <sample_height = %d>]\n”//預設24*24
    "  [-info <collection_file_name>]\n"
    "  [-img <image_file_name>]\n"
    "  [-vec <vec_file_name>]\n"
    "  [-bg <background_file_name>]\n  [-num <number_of_samples = %d>]\n"
    "  [-bgcolor <background_color = %d>]\n"
    "  [-inv] [-randinv] [-bgthresh <background_color_threshold = %d>]\n"
    "  [-maxidev <max_intensity_deviation = %d>]\n"
    "  [-maxxangle <max_x_rotation_angle = %f>]\n"
    "  [-maxyangle <max_y_rotation_angle = %f>]\n"
    "  [-maxzangle <max_z_rotation_angle = %f>]\n"
    "  [-show [<scale = %f>]]\n"
    "  [-w <sample_width = %d>]\n  [-h <sample_height = %d>]\n"//預設24*24

以下1)~4)是按順序判斷,且有且僅有一個

1)提供imagename 和vecname時,呼叫以下操作
[cpp] view plain copy print?在CODE上檢視程式碼片派生到我的程式碼片
  1. /* 
  2.  * cvCreateTrainingSamples 
  3.  * 
  4.  * Create training samples applying random distortions to sample image and 
  5.  * store them in .vec file 
  6.  * 
  7.  * filename        - .vec file name 
  8.  * imgfilename     - sample image file name 
  9.  * bgcolor         - background color for sample image 
  10.  * bgthreshold     - background color threshold. Pixels those colors are in range 
  11.  *   [bgcolor-bgthreshold, bgcolor+bgthreshold] are considered as transparent 
  12.  * bgfilename      - background description file name. If not NULL samples 
  13.  *   will be put on arbitrary background 
  14.  * count           - desired number of samples 
  15.  * invert          - if not 0 sample foreground pixels will be inverted 
  16.  *   if invert == CV_RANDOM_INVERT then samples will be inverted randomly 
  17.  * maxintensitydev - desired max intensity deviation of foreground samples pixels 
  18.  * maxxangle       - max rotation angles 
  19.  * maxyangle 
  20.  * maxzangle 
  21.  * showsamples     - if not 0 samples will be shown 
  22.  * winwidth        - desired samples width 
  23.  * winheight       - desired samples height 
  24.  */
/*
 * cvCreateTrainingSamples
 *
 * Create training samples applying random distortions to sample image and
 * store them in .vec file
 *
 * filename        - .vec file name
 * imgfilename     - sample image file name
 * bgcolor         - background color for sample image
 * bgthreshold     - background color threshold. Pixels those colors are in range
 *   [bgcolor-bgthreshold, bgcolor+bgthreshold] are considered as transparent
 * bgfilename      - background description file name. If not NULL samples
 *   will be put on arbitrary background
 * count           - desired number of samples
 * invert          - if not 0 sample foreground pixels will be inverted
 *   if invert == CV_RANDOM_INVERT then samples will be inverted randomly
 * maxintensitydev - desired max intensity deviation of foreground samples pixels
 * maxxangle       - max rotation angles
 * maxyangle
 * maxzangle
 * showsamples     - if not 0 samples will be shown
 * winwidth        - desired samples width
 * winheight       - desired samples height
 */
2)提供imagename、bgfilename和infoname時
與1)類似
3)提供 infoname和 vecname時,呼叫以下操作(這裡是我們訓練需要的)
[cpp] view plain copy print?在CODE上檢視程式碼片派生到我的程式碼片
  1. /* 
  2.  * cvCreateTrainingSamplesFromInfo 
  3.  * 
  4.  * Create training samples from a set of marked up images and store them into .vec file 
  5.  * infoname    - file in which marked up image descriptions are stored 
  6.  * num         - desired number of samples 
  7.  * showsamples - if not 0 samples will be shown 
  8.  * winwidth    - sample width 
  9.  * winheight   - sample height 
  10.  *  
  11.  * Return number of successfully created samples 
  12.  */
  13. int cvCreateTrainingSamplesFromInfo( constchar* infoname, constchar* vecfilename,  
  14.                                      int num,  
  15.                                      int showsamples,  
  16.                                      int winwidth, int winheight )  
/*
 * cvCreateTrainingSamplesFromInfo
 *
 * Create training samples from a set of marked up images and store them into .vec file
 * infoname    - file in which marked up image descriptions are stored
 * num         - desired number of samples
 * showsamples - if not 0 samples will be shown
 * winwidth    - sample width
 * winheight   - sample height
 * 
 * Return number of successfully created samples
 */
int cvCreateTrainingSamplesFromInfo( const char* infoname, const char* vecfilename,
                                     int num,
                                     int showsamples,
                                     int winwidth, int winheight )

函式內容:讀取當前圖中所有標記的sample(x,y,w,h),並將其縮放到winwidth、winheight大小,故在這之前的人為縮放操作不需要

(可以看到,僅需要num、w、h引數)
4)僅vecname時,可以將vec裡面的所有縮放後的samples都顯示出來
[cpp] view plain copy print?在CODE上檢視程式碼片派生到我的程式碼片
  1. /* 
  2.  * cvShowVecSamples 
  3.  * 
  4.  * Shows samples stored in .vec file 
  5.  * 
  6.  * filename 
  7.  *   .vec file name 
  8.  * winwidth 
  9.  *   sample width 
  10.  * winheight 
  11.  *   sample height 
  12.  * scale 
  13.  *   the scale each sample is adjusted to(這個scale與3中的縮放不是一回事,這裡僅為了顯示而再次縮放) 
  14.  */
  15. void cvShowVecSamples( constchar* filename, int winwidth, int winheight, double scale );  
/*
 * cvShowVecSamples
 *
 * Shows samples stored in .vec file
 *
 * filename
 *   .vec file name
 * winwidth
 *   sample width
 * winheight
 *   sample height
 * scale
 *   the scale each sample is adjusted to(這個scale與3中的縮放不是一回事,這裡僅為了顯示而再次縮放)
 */
void cvShowVecSamples( const char* filename, int winwidth, int winheight, double scale );

2、opencv_haartraining.exe的引數

(haartraining.cpp )

[cpp] view plain copy print?在CODE上檢視程式碼片派生到我的程式碼片
  1. ”  -data <dir_name>\n”
  2. ”  -vec <vec_file_name>\n”
  3. ”  -bg <background_file_name>\n”
  4. ”  [-bg-vecfile]\n”
  5. ”  [-npos <number_of_positive_samples = %d>]\n”
  6. ”  [-nneg <number_of_negative_samples = %d>]\n”
  7. ”  [-nstages <number_of_stages = %d>]\n”
  8. ”  [-nsplits <number_of_splits = %d>]\n”
  9. ”  [-mem <memory_in_MB = %d>]\n”
  10. ”  [-sym (default)] [-nonsym]\n”
  11. ”  [-minhitrate <min_hit_rate = %f>]\n”
  12. ”  [-maxfalsealarm <max_false_alarm_rate = %f>]\n”
  13. ”  [-weighttrimming <weight_trimming = %f>]\n”
  14. ”  [-eqw]\n”
  15. ”  [-mode <BASIC (default) | CORE | ALL>]\n”
  16. ”  [-w <sample_width = %d>]\n”
  17. ”  [-h <sample_height = %d>]\n”
  18. ”  [-bt <DAB | RAB | LB | GAB (default)>]\n”
  19. ”  [-err <misclass (default) | gini | entropy>]\n”
  20. ”  [-maxtreesplits <max_number_of_splits_in_tree_cascade = %d>]\n”
  21. ”  [-minpos <min_number_of_positive_samples_per_cluster = %d>]\n”
"  -data <dir_name>\n"
"  -vec <vec_file_name>\n"
"  -bg <background_file_name>\n"
"  [-bg-vecfile]\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"

3、opencv_performance.exe引數

(performance.cpp )

[cpp] view plain copy print?在CODE上檢視程式碼片派生到我的程式碼片
  1. ”  -data <classifier_directory_name>\n”
  2. ”  -info <collection_file_name>\n”
  3. ”  [-maxSizeDiff <max_size_difference = %f>]\n”
  4. ”  [-maxPosDiff <max_position_difference = %f>]\n”
  5. ”  [-sf <scale_factor = %f>]\n”
  6. ”  [-ni <saveDetected = 0>]\n”
  7. ”  [-nos <number_of_stages = %d>]\n”
  8. ”  [-rs <roc_size = %d>]\n”
  9. ”  [-w <sample_width = %d>]\n”
  10. ”  [-h <sample_height = %d>]\n”
"  -data <classifier_directory_name>\n"
"  -info <collection_file_name>\n"
"  [-maxSizeDiff <max_size_difference = %f>]\n"
"  [-maxPosDiff <max_position_difference = %f>]\n"
"  [-sf <scale_factor = %f>]\n"
"  [-ni <saveDetected = 0>]\n"
"  [-nos <number_of_stages = %d>]\n"
"  [-rs <roc_size = %d>]\n"
"  [-w <sample_width = %d>]\n"
"  [-h <sample_height = %d>]\n"

4、opencv_traincascade.exe引數說明

——traincascade.cpp 

[cpp] view plain copy print?在CODE上檢視程式碼片派生到我的程式碼片
  1.  cout << “Usage: ” << argv[0] << endl;  
  2.  cout << ”  -data <cascade_dir_name>” << endl;  
  3.  cout << ”  -vec <vec_file_name>” << endl;  
  4.  cout << ”  -bg <background_file_name>” << endl;  
  5.  cout << ”  [-numPos <number_of_positive_samples = ” << numPos << “>]” << endl;   //預設2000
  6.  cout << ”  [-numNeg <number_of_negative_samples = ” << numNeg << “>]” << endl;   //預設1000
  7.  cout << ”  [-numStages <number_of_stages = ” << numStages << “>]” << endl;   //預設20
  8.  cout << ”  [-precalcValBufSize <precalculated_vals_buffer_size_in_Mb = ” << precalcValBufSize << “>]” << endl;//預設256
  9.  cout << ”  [-precalcIdxBufSize <precalculated_idxs_buffer_size_in_Mb = ” << precalcIdxBufSize << “>]” << endl;//預設256
  10.  cout << ”  [-baseFormatSave]” << endl;                     //是否按照舊版存xml檔案預設false
  11. // cout << ”  [-numThreads <max_number_of_threads = ” << numThreads << ”>]” << endl;//這個引數在3.0版本中才出現,預設numThreads = getNumThreads();
  12. // cout << ”  [-acceptanceRatioBreakValue <value> = ” << acceptanceRatioBreakValue << ”>]” << endl;//這個引數在3.0版本中才出現,預設-1.0
  13.  cascadeParams.printDefaults();  
  14.  stageParams.printDefaults();  
  15.  forint fi = 0; fi < fc; fi++ )  
  16.      featureParams[fi]->printDefaults();  
        cout << "Usage: " << argv[0] << endl;
        cout << "  -data <cascade_dir_name>" << endl;
        cout << "  -vec <vec_file_name>" << endl;
        cout << "  -bg <background_file_name>" << endl;
        cout << "  [-numPos <number_of_positive_samples = " << numPos << ">]" << endl;    //預設2000
        cout << "  [-numNeg <number_of_negative_samples = " << numNeg << ">]" << endl;    //預設1000
        cout << "  [-numStages <number_of_stages = " << numStages << ">]" << endl;    //預設20
        cout << "  [-precalcValBufSize <precalculated_vals_buffer_size_in_Mb = " << precalcValBufSize << ">]" << endl;//預設256
        cout << "  [-precalcIdxBufSize <precalculated_idxs_buffer_size_in_Mb = " << precalcIdxBufSize << ">]" << endl;//預設256
        cout << "  [-baseFormatSave]" << endl;                      //是否按照舊版存xml檔案預設false
       // cout << "  [-numThreads <max_number_of_threads = " << numThreads << ">]" << endl;//這個引數在3.0版本中才出現,預設numThreads = getNumThreads();
       // cout << "  [-acceptanceRatioBreakValue <value> = " << acceptanceRatioBreakValue << ">]" << endl;//這個引數在3.0版本中才出現,預設-1.0
        cascadeParams.printDefaults();
        stageParams.printDefaults();
        for( int fi = 0; fi < fc; fi++ )
            featureParams[fi]->printDefaults();

其中cascadeParams.printDefaults();——cascadeclassifier.cpp 如下

[cpp] view plain copy print?在CODE上檢視程式碼片派生到我的程式碼片
  1. cout << “  [-stageType <”;                                                 //預設BOOST
  2. forint i = 0; i < (int)(sizeof(stageTypes)/sizeof(stageTypes[0])); i++ )  
  3. {  
  4.     cout << (i ? ” | ” : “”) << stageTypes[i];  
  5.     if ( i == defaultStageType )  
  6.         cout << ”(default)”;  
  7. }  
  8. cout << ”>]” << endl;  
  9. cout << ”  [-featureType <{“;                                              //預設HAAR
  10. forint i = 0; i < (int)(sizeof(featureTypes)/sizeof(featureTypes[0])); i++ )  
  11. {  
  12.     cout << (i ? ”, ” : “”) << featureTypes[i];  
  13.     if ( i == defaultStageType )  
  14.         cout << ”(default)”;  
  15. }  
  16. cout << ”}>]” << endl;  
  17. cout << ”  [-w <sampleWidth = ” << winSize.width << “>]” << endl;        //預設24*24
  18. cout << ”  [-h <sampleHeight = ” << winSize.height << “>]” << endl;  
    cout << "  [-stageType <";                                                 //預設BOOST
    for( int i = 0; i < (int)(sizeof(stageTypes)/sizeof(stageTypes[0])); i++ )
    {
        cout << (i ? " | " : "") << stageTypes[i];
        if ( i == defaultStageType )
            cout << "(defau