日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人工智能 > pytorch >内容正文

pytorch

createsamples.cpp中生成vec文件的实现及详细注释、图解——人脸识别的尝试系列(三)

發布時間:2024/7/23 pytorch 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 createsamples.cpp中生成vec文件的实现及详细注释、图解——人脸识别的尝试系列(三) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在我們開始訓練我們的Haar分類器之前,首先要對樣本進行處理。

人臉識別的嘗試系列(一)中:http://blog.csdn.net/u011583927/article/details/44627493

我們已經提到了如何準備我們的樣本,在如下圖準備好樣本之后


需要在cmd窗口中調用類似如下的命令生成vec文件

opencv_createsamples.exe–vec pos.vec –info pos_image.txt –bg neg_image.txt –w 24 –h 24 –num 400

那么具體是如何生成的vec文件的,下面是具體的實現代碼以及根據我個人理解加上的詳細注釋

為方便大家理解,代碼中插入了兩張圖片,分別展示了相應區域代碼的執行結果


/** createsamples.cpp 生成vec文件的可執行程序的具體實現** Create test/training samples 利用描述正樣本和負樣本的txt文件創建vec文件* 命令行示例: opencv_createsamples.exe –vec pos.vec –info pos_image.txt –bg neg_image.txt –w 24 –h 24 –num 400 *需要先將命令行的地址調到當前文件夾下*/#include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <ctime> #include <memory>using namespace std;#include "cvhaartraining.h" #include "ioutput.h"int main( int argc, char* argv[] ) {//參數初始化int i = 0;char* nullname = (char*)"(NULL)";char* vecname = NULL; /* .vec file name */char* infoname = NULL; //file name with marked up image descriptions正樣本描述文件路徑char* imagename = NULL; /* single sample image 單個正樣本圖片*/char* bgfilename = NULL; /* background 負樣本描述文件路徑 */int num = 1000;int bgcolor = 0;int bgthreshold = 80;int invert = 0;int maxintensitydev = 40;// max_intensity_deviationdouble maxxangle = 1.1;double maxyangle = 1.1;double maxzangle = 0.5;bool showsamples = false;/* the samples are adjusted to this scale in the sample preview window */double scale = 4.0;int width = 24;int height = 24;bool pngoutput = false; /* whether to make the samples in png or in jpg*/srand((unsigned int)time(0));//如果只輸入opencv_createsamples.exe 相當于查看命令行參數使用if( argc == 1 ){printf( "Usage: %s\n [-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"" [-pngoutput]",argv[0], num, bgcolor, bgthreshold, maxintensitydev,maxxangle, maxyangle, maxzangle, scale, width, height );return 0;}

for( i = 1; i < argc; ++i ) {//strcmp(str1,str2)函數:比較兩個字符串。 //相等返回0;str1>str2返回正數;str1<str2返回負數if( !strcmp( argv[i], "-info" ) ){//argv[i]==”-info”infoname = argv[++i];}else if( !strcmp( argv[i], "-img" ) ){imagename = argv[++i];}else if( !strcmp( argv[i], "-vec" ) ){vecname = argv[++i];}else if( !strcmp( argv[i], "-bg" ) ){bgfilename = argv[++i];}else if( !strcmp( argv[i], "-num" ) ){//atoi 把一個字符串轉化成整形num = atoi( argv[++i] );}else if( !strcmp( argv[i], "-bgcolor" ) ){bgcolor = atoi( argv[++i] );}else if( !strcmp( argv[i], "-bgthresh" ) ){bgthreshold = atoi( argv[++i] );}else if( !strcmp( argv[i], "-inv" ) ){//輸入含-inv指令invert = 1;}else if( !strcmp( argv[i], "-randinv" ) ){//輸入含-randinv指令invert = CV_RANDOM_INVERT;}else if( !strcmp( argv[i], "-maxidev" ) ){maxintensitydev = atoi( argv[++i] );}else if( !strcmp( argv[i], "-maxxangle" ) ){maxxangle = atof( argv[++i] );}else if( !strcmp( argv[i], "-maxyangle" ) ){maxyangle = atof( argv[++i] );}else if( !strcmp( argv[i], "-maxzangle" ) ){maxzangle = atof( argv[++i] );}else if( !strcmp( argv[i], "-show" ) ){showsamples = true;if( i+1 < argc && strlen( argv[i+1] ) > 0 && argv[i+1][0] != '-' ){double d;d = strtod( argv[i+1], 0 );if( d != -HUGE_VAL && d != HUGE_VAL && d > 0 ) scale = d;++i;}}else if( !strcmp( argv[i], "-w" ) ){width = atoi( argv[++i] );}else if( !strcmp( argv[i], "-h" ) ){height = atoi( argv[++i] );}else if( !strcmp( argv[i], "-pngoutput" ) ){pngoutput = true;}}printf( "Info file name: %s\n", ((infoname == NULL) ? nullname : infoname ) );printf( "Img file name: %s\n", ((imagename == NULL) ? nullname : imagename ) );printf( "Vec file name: %s\n", ((vecname == NULL) ? nullname : vecname ) );printf( "BG file name: %s\n", ((bgfilename == NULL) ? nullname : bgfilename ) );printf( "Num: %d\n", num );printf( "BG color: %d\n", bgcolor );printf( "BG threshold: %d\n", bgthreshold );printf( "Invert: %s\n", (invert == CV_RANDOM_INVERT) ? "RANDOM": ( (invert) ? "TRUE" : "FALSE" ) );printf( "Max intensity deviation: %d\n", maxintensitydev );printf( "Max x angle: %g\n", maxxangle );printf( "Max y angle: %g\n", maxyangle );printf( "Max z angle: %g\n", maxzangle );printf( "Show samples: %s\n", (showsamples) ? "TRUE" : "FALSE" );if( showsamples ){printf( "Scale applied to display : %g\n", scale );}if( !pngoutput){printf( "Original image will be scaled to:\n");printf( "\tWidth: $backgroundWidth / %d\n", width );printf( "\tHeight: $backgroundHeight / %d\n", height );}/* determine action (通過關鍵命令)確定行為*/if( imagename && vecname ){printf( "Create training samples from single image applying distortions...\n" );cvCreateTrainingSamples( vecname, imagename, bgcolor, bgthreshold, bgfilename,num, invert, maxintensitydev,maxxangle, maxyangle, maxzangle,showsamples, width, height );printf( "Done\n" );}else if( imagename && bgfilename && infoname){printf( "Create data set from single image applying distortions...\n""Output format: %s\n",(( pngoutput ) ? "PNG" : "JPG") );std::auto_ptr<DatasetGenerator> creator;if( pngoutput ){creator = std::auto_ptr<DatasetGenerator>( new PngDatasetGenerator( infoname ) );}else{creator = std::auto_ptr<DatasetGenerator>( new JpgDatasetGenerator( infoname ) );}creator->create( imagename, bgcolor, bgthreshold, bgfilename, num,invert, maxintensitydev, maxxangle, maxyangle, maxzangle,showsamples, width, height );printf( "Done\n" );}else if( infoname && vecname ) {//生成vec文件,我們使用的這種命令//命令包括正樣本描述文件的文件名,準備生成的vec文件的文件名int total;printf( "Create training samples from images collection...\n" );total = cvCreateTrainingSamplesFromInfo( infoname, vecname, num, showsamples,width, height );printf( "Done. Created %d samples\n", total );}else if( vecname ) {//查看vec文件//命令不包含正樣本文件,背景樣本文件,單個正樣本圖像,只包含vec文件路徑

printf( "View samples from vec file (press ESC to exit)...\n" );cvShowVecSamples( vecname, width, height, scale );printf( "Done\n" );}else{printf( "Nothing to do\n" );}return 0; }cvCreateTrainingSamplesFromInfo函數的具體實現 為方便理解,對應于上面我們輸入的命令來進行解釋 -infoname pos_image.txt 正樣本描述文件文件名 -vecfilename pos.vec 這個參數相當于指定創建的vec文件的名字,函數執行前這個vec文件并不存在 -num 400 正樣本總數 -showsamples false 是否顯示樣本 -width -height int cvCreateTrainingSamplesFromInfo( const char* infoname, const char* vecfilename,int num,int showsamples,int winwidth, int winheight ) {char fullname[PATH_MAX];char* filename;FILE* info;FILE* vec;IplImage* src=0;IplImage* sample;int line;int error;int i;int x, y, width, height;int total;/* #include <assert.h> void assert( int expression ); assert的作用是現計算表達式 expression ,如果其值為假(即為0),那么它先向stderr打印一條出錯信息,然后通過調用 abort 來終止程序運行。*/assert( infoname != NULL );assert( vecfilename != NULL );total = 0;if( !icvMkDir( vecfilename ) ) {// icvMkDir() //個人理解:判斷文件名vecfilename是否只包含文件名,不包含路徑//例如:pos.veg返回1 D:\\pos.veg返回0//若只包含文件名,返回1,否則返回0#if CV_VERBOSEfprintf( stderr, "Unable to create directory hierarchy: %s\n", vecfilename ); #endif /* CV_VERBOSE */return total;}info = fopen( infoname, "r" );//以只讀方式打開文件infoname,若文件不存在不創建該文件(即返回null)if( info == NULL ){#if CV_VERBOSEfprintf( stderr, "Unable to open file: %s\n", infoname ); #endif /* CV_VERBOSE */return total;}vec = fopen( vecfilename, "wb" );// 以二進制寫方式打開文件,若文件不存在則創建該文件if( vec == NULL ){#if CV_VERBOSEfprintf( stderr, "Unable to open file: %s\n", vecfilename ); #endif /* CV_VERBOSE */fclose( info );return total;}//創建一個單通道byte圖像sample = cvCreateImage( cvSize( winwidth, winheight ), IPL_DEPTH_8U, 1 );//寫vec文件頭icvWriteVecHeader( vec, num, sample->width, sample->height );if( showsamples ){cvNamedWindow( "Sample", CV_WINDOW_AUTOSIZE );}strcpy( fullname, infoname );/*strrchr() 函數查找字符在指定字符串中從后面開始的第一次出現的位置,如果成功,則返回從該位置到字符串結尾的所有字符,如果失敗,則返回 false。與之相對應的是strchr()函數,它查找字符串中首次出現指定字符的位置。*/filename = strrchr( fullname, '\\' );//獲取正樣本描述文件的文件名,剔除路徑if( filename == NULL ){filename = strrchr( fullname, '/' );}if( filename == NULL ){filename = fullname;}else {//正常情況,將指針指向‘\’后面的第一個字符filename++;}//遍歷每張正樣本圖片,將其信息寫入vec文件for( line = 1, error = 0, total = 0; total < num ;line++ ){int count;/* fscanf功能: 從一個流中執行格式化輸入,fscanf遇到空格和換行時結束,注意空格時也結束。 intfscanf(FILE*stream,constchar*format,[argument...]); FILE *stream:文件指針; char *format:格式字符串; [argument...]:輸入列表。 返回值:整型,成功讀入的參數的個數 */error = ( fscanf( info, "%s %d", filename, &count ) != 2 ); //info——正樣本描述文件的文件流 // 正樣本描述文件每一行的格式 pos_image/0.bmp 1 0 0 24 24 //注意!filename是指向fullname的指針。所以這里以filename作為讀入數據的參數,實際上修改的是fullname的內容。讀入信息后fullname表示某一個正樣本圖片的地址(相對路徑) //count 表示文件的個數if( !error )//說明讀取是正確的,獲取樣本圖片{src = cvLoadImage( fullname, 0 );//讀取一副正樣本圖像(強制轉化為灰度圖像)error = ( src == NULL );if( error ){#if CV_VERBOSEfprintf( stderr, "Unable to open image: %s\n", fullname ); #endif /* CV_VERBOSE */}}//遍歷當前樣本圖片中的所有子窗口樣本。//一般情況下的使用方法是只有一個子窗口也就是整幅樣本圖片, 即count=1,且x=0 y=0 width height就是樣本的寬和高 for( i = 0; (i < count) && (total < num); i++, total++ ){error = ( fscanf( info, "%d %d %d %d", &x, &y, &width, &height ) != 4 );//讀取當前圖像的頂點坐標以及長寬if( error ) break;// cvSetImageROI 基于給定的矩形設置圖像的ROI(感興趣區域)cvSetImageROI( src, cvRect( x, y, width, height ) );void cvResize( const CvArr* src, CvArr* dst, int interpolation=CV_INTER_LINEAR );函數cvResize()功能: 重新調整圖像src(或它的ROI),使它精確匹配目標dst(或其ROI)。這里需要說明的是,cvResize可以用來調整3通道圖像(如RGB圖像)和單通道圖像的大小。src 源圖像; dst 目標圖像cvResize( src, sample, width >= sample->width &&height >= sample->height ? CV_INTER_AREA : CV_INTER_LINEAR );if( showsamples ){cvShowImage( "Sample", sample );if( cvWaitKey( 0 ) == 27 ){showsamples = 0;}}//將當前這幅樣本圖片信息寫入vec文件中icvWriteVecSample( vec, sample );}//釋放當前的圖片占用的內存if( src ){cvReleaseImage( &src );}if( error ){#if CV_VERBOSEfprintf( stderr, "%s(%d) : parse error", infoname, line ); #endif /* CV_VERBOSE */break;}}if( sample ){cvReleaseImage( &sample );}fclose( vec );fclose( info );return total; }



總結

以上是生活随笔為你收集整理的createsamples.cpp中生成vec文件的实现及详细注释、图解——人脸识别的尝试系列(三)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。