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?- #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>
- usingnamespace std;
- usingnamespace 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;
- }
#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?- ” [-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
" [-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?
- /*
- * 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
- */
/*
* 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?
- /*
- * 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( constchar* infoname, constchar* vecfilename,
- int num,
- int showsamples,
- 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大小,故在這之前的人為縮放操作不需要
4)僅vecname時,可以將vec裡面的所有縮放後的samples都顯示出來
[cpp] view plain copy print?
- /*
- * 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( 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?- ” -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”
" -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?- ” -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”
" -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?- 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();
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?- cout << “ [-stageType <”; //預設BOOST
- for( int i = 0; i < (int)(sizeof(stageTypes)/sizeof(stageTypes[0])); i++ )
- {
- cout << (i ? ” | ” : “”) << stageTypes[i];
- if ( i == defaultStageType )
- cout << ”(default)”;
- }
- cout << ”>]” << endl;
- cout << ” [-featureType <{“; //預設HAAR
- for( int i = 0; i < (int)(sizeof(featureTypes)/sizeof(featureTypes[0])); i++ )
- {
- cout << (i ? ”, ” : “”) << featureTypes[i];
- if ( i == defaultStageType )
- cout << ”(default)”;
- }
- cout << ”}>]” << endl;
- cout << ” [-w <sampleWidth = ” << winSize.width << “>]” << endl; //預設24*24
- 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