linux下編譯mergevec和vec2img

用opencv訓練分類器比較有用的兩個輔助工具。


項目主頁:http://note.sonots.com/SciSoftware/haartraining.html#v6f077ba

項目主頁上有編譯好的exe文件,但沒有linux下面編譯好的二進制文件。


mergevec用於合併多個vec文件。

用法:

mergevec
  <collection_file_of_vecs> #類似於創建樣本和訓練的描述文件,一個存有要合併的vec文件路徑列表的文件,可用find命令查找並重定向生成
  <output_vec_filename> #輸出vec文件名
  [-show] #與創建樣本時的show參數一樣,
  [-w <sample_width = 24>] #不解釋
  [-h <sample_height = 24>] #不解釋

vec2img用於從vec文件中釋放圖像文件

用法:

vec2img
  <input_vec_filename> #指定vec文件
  <output_filename_format> #指定輸出文件格式,是一個含有%d格式的文件名字串,擴展名決定圖像文件的輸出格式,如test_%04d.png
  [-w <sample_width = 24>] #不解釋
  [-h <sample_height = 24>] #不解釋

編譯:

下載兩個文件的源碼,因爲都是單個文件,這裏我貼出來:

mergevec.cpp

#include <cv.h>
#include <highgui.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#include "cvhaartraining.h"
#include "_cvhaartraining.h" // Load CvVecFile
// Write a vec header into the vec file (located at cvsamples.cpp)
void icvWriteVecHeader( FILE* file, int count, int width, int height );
// Write a sample image into file in the vec format (located at cvsamples.cpp)
void icvWriteVecSample( FILE* file, CvArr* sample );
// Append the body of the input vec to the ouput vec
void icvAppendVec( CvVecFile &in, CvVecFile &out, int *showsamples, int winwidth, int winheight );
// Merge vec files
void icvMergeVecs( char* infoname, const char* outvecname, int showsamples, int width, int height );

// Append the body of the input vec to the ouput vec
void icvAppendVec( CvVecFile &in, CvVecFile &out, int *showsamples, int winwidth, int winheight )
{
    CvMat* sample;

    if( *showsamples )
    {
        cvNamedWindow( "Sample", CV_WINDOW_AUTOSIZE );
    }
    if( !feof( in.input ) )
    {
        in.last = 0;
        in.vector = (short*) cvAlloc( sizeof( *in.vector ) * in.vecsize );
        if ( *showsamples )
        {
            if ( in.vecsize != winheight * winwidth )
            {
                fprintf( stderr, "ERROR: -show: the size of images inside of vec files does not match with %d x %d, but %d\n", winheight, winwidth, in.vecsize );
                exit(1);
            }
            sample = cvCreateMat( winheight, winwidth, CV_8UC1 );
        } 
        else 
        {
            sample = cvCreateMat( in.vecsize, 1, CV_8UC1 );
        }
        for( int i = 0; i < in.count; i++ )
        {
            icvGetHaarTraininDataFromVecCallback( sample, &in );
            icvWriteVecSample ( out.input, sample );
            if( *showsamples )
            {
                cvShowImage( "Sample", sample );
                if( cvWaitKey( 0 ) == 27 )
                { 
                    *showsamples = 0; 
                }
            }
        }
        cvReleaseMat( &sample );
        cvFree( (void**) &in.vector );
    }
}

void icvMergeVecs( char* infoname, const char* outvecname, int showsamples, int width, int height )
{
    char onevecname[PATH_MAX];
    int i = 0;
    int filenum = 0;
    short tmp; 
    FILE *info;
    CvVecFile outvec;
    CvVecFile invec;
    int prev_vecsize;

    // fopen input and output file
    info = fopen( infoname, "r" );
    if ( info == NULL )
    {
        fprintf( stderr, "ERROR: Input file %s does not exist or not readable.\n", infoname );
        exit(1);
    }
    outvec.input = fopen( outvecname, "wb" );
    if ( outvec.input == NULL )
    {
        fprintf( stderr, "ERROR: Output file %s is not writable.\n", outvecname );
        exit(1);
    }

    // Header
    rewind( info );
    outvec.count = 0;
    for ( filenum = 0; ; filenum++ )
    {
        if ( fscanf( info, "%s", onevecname ) == EOF )
        {
            break;
        }
        invec.input = fopen( onevecname, "rb" );
        if ( invec.input == NULL )
        {
            fprintf( stderr, "ERROR: Input file %s does not exist or not readable.\n", onevecname );
            exit(1);
        }
        fread( &invec.count,   sizeof( invec.count )  , 1, invec.input );
        fread( &invec.vecsize, sizeof( invec.vecsize ), 1, invec.input );
        fread( &tmp, sizeof( tmp ), 1, invec.input );
        fread( &tmp, sizeof( tmp ), 1, invec.input );

        outvec.count += invec.count;
        if( i > 0 &&  invec.vecsize != prev_vecsize )
        {
            fprintf( stderr, "ERROR: The size of images in %s(%d) is different with the previous vec file(%d).\n", onevecname, invec.vecsize, prev_vecsize );
            exit(1);
        }
        prev_vecsize = invec.vecsize;
        fclose( invec.input );
    }
    outvec.vecsize = invec.vecsize;
    icvWriteVecHeader( outvec.input, outvec.count, outvec.vecsize, 1);

    // Contents
    rewind( info );
    outvec.count = 0;
    for ( i = 0; i < filenum ; i++ )
    {
        if (fscanf( info, "%s", onevecname ) == EOF) {
            break;
        }
        invec.input = fopen( onevecname, "rb" );
        fread( &invec.count,   sizeof( invec.count )  , 1, invec.input );
        fread( &invec.vecsize, sizeof( invec.vecsize ), 1, invec.input );
        fread( &tmp, sizeof( tmp ), 1, invec.input );
        fread( &tmp, sizeof( tmp ), 1, invec.input );

        icvAppendVec( invec, outvec, &showsamples, width, height );
        fclose( invec.input );
    }
    fclose( outvec.input );
}

int main( int argc, char **argv ) 
{
    int i;
    char *infoname   = NULL;
    char *outvecname = NULL;
    int showsamples  = 0;
    int width        = 24;
    int height       = 24;

    if( argc == 1 )
    {
        printf( "Usage: %s\n  <collection_file_of_vecs>\n"
            "  <output_vec_filename>\n"
            "  [-show] [-w <sample_width = %d>] [-h <sample_height = %d>]\n",
            argv[0], width, height );
        return 0;
    }
    for( i = 1; i < argc; ++i )
    {
        if( !strcmp( argv[i], "-show" ) )
        {
            showsamples = 1;
            // width = atoi( argv[++i] ); // obsolete -show width height
            // height = atoi( argv[++i] );
        } 
        else if( !strcmp( argv[i], "-w" ) )
        {
            width = atoi( argv[++i] );
        } 
        else if( !strcmp( argv[i], "-h" ) )
        {
            height = atoi( argv[++i] );
        }
        else if( argv[i][0] == '-' )
        {
            fprintf( stderr, "ERROR: The option %s does not exist. n", argv[i] );
            exit(1);
        }
        else if( infoname == NULL )
        {
            infoname = argv[i];
        }
        else if( outvecname == NULL )
        {
            outvecname = argv[i];
        }
    }
    if( infoname == NULL )
    {
        fprintf( stderr, "ERROR: No input file\n" );
        exit(1);
    }
    if( outvecname == NULL )
    {
        fprintf( stderr, "ERROR: No output file\n" );
        exit(1);
    }
    icvMergeVecs( infoname, outvecname, showsamples, width, height );
    return 0;
}


vec2img.cpp

#include <cv.h>
#include <highgui.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#include "cvhaartraining.h"
#include "_cvhaartraining.h" // Load CvVecFile
void icvVec2Img( const char* vecname, const char* outformat, int width, int height );

// Extract images from a vec file
void icvVec2Img( const char* vecname, const char* outformat, int width, int height )
{
    CvVecFile vec;
    CvMat* sample;
    char outfilename[PATH_MAX];
    short tmp;

    vec.input = fopen( vecname, "rb" );
    if ( vec.input == NULL )
    {
        fprintf( stderr, "ERROR: Input file %s does not exist or not readable.\n", vecname);
        exit(1);
    }
    fread( &vec.count, sizeof( vec.count ), 1, vec.input );
    fread( &vec.vecsize, sizeof( vec.vecsize ), 1, vec.input );
    fread( &tmp, sizeof( tmp ), 1, vec.input );
    fread( &tmp, sizeof( tmp ), 1, vec.input );

    if( !feof( vec.input ) )
    {
        vec.last = 0;
        vec.vector = (short*) cvAlloc( sizeof( *vec.vector ) * vec.vecsize );
        if( vec.vecsize != width * height )
        {
            fprintf( stderr, "ERROR: The size of images inside of vec files does not match with %d x %d, but %d. \n", height, width, vec.vecsize );
            exit(1);
        }
        sample = cvCreateMat( height, width, CV_8UC1 );
        //cvNamedWindow( "Sample", CV_WINDOW_AUTOSIZE );
        for( int i = 0; i < vec.count; i++ )
        {
            icvGetHaarTraininDataFromVecCallback( sample, &vec );
            sprintf( outfilename, outformat, i + 1 );
            printf( "%s\n", outfilename );
            cvSaveImage( outfilename, sample );
            //cvShowImage( "Sample", sample ); cvWaitKey( 0 );
        }
        cvReleaseMat( &sample );
        cvFree( (void**) &vec.vector );
    }
    fclose( vec.input );
}

int main(int argc, char **argv){
    char *vecname   = NULL;
    char *outformat = NULL;
    int width       = 24;
    int height      = 24;
    int i           = 0;

    if( argc == 1 )
    {
        printf( "Usage: %s\n  <input_vec_filename>\n"
            "  <output_filename_format>\n"
            "  [-w <sample_width = %d>] [-h <sample_height = %d>]\n",
            argv[0], width, height );
        printf( "The output filename format is a string having one %%d such as 'samples%%04d.png'.\n"
            "The image file format is automatically determined by the extension.\n" );
        return 0;
    }
    for( i = 1; i < argc; ++i )
    {
        if( !strcmp( argv[i], "-w" ) )
        {
            width = atoi( argv[++i] );
        } 
        else if( !strcmp( argv[i], "-h" ) )
        {
            height = atoi( argv[++i] );
        } 
        else if( vecname == NULL )
        {
            vecname = argv[i];
        }
        else if( outformat == NULL )
        {
            outformat = argv[i];
        }
    }
    if ( vecname == NULL )
    {
        fprintf( stderr, "ERROR: No input vec file. \n" );
        exit(1);
    }
    if ( outformat == NULL )
    {
        fprintf( stderr, "ERROR: Not output filename format. \n" );
        exit(1);
    }
    icvVec2Img( vecname, outformat, width, height );
    return 0;
}


編譯的話,將兩個文件複製到opencv源碼中的apps/haartraining/路徑下

編譯前,代碼需要調整一下,將頭文件

#include <cvhaartraining.h>
#include <_cvhaartraining.h> // Load CvVecFile

中的<>換成“”,讓其在當前路徑中尋找頭文件,上面我貼出來的代碼是已經調整過的。

編譯命令:

mergevec.cpp

$ g++ `pkg-config --cflags --libs opencv` -o mergevec mergevec.cpp cvboost.cpp cvcommon.cpp cvsamples.cpp cvhaarclassifier.cpp cvhaartraining.cpp
vec2img.cpp

$ g++ `pkg-config --cflags --libs opencv` -o vec2img vec2img.cpp cvboost.cpp cvcommon.cpp cvsamples.cpp cvhaarclassifier.cpp cvhaartraining.cpp







發佈了53 篇原創文章 · 獲贊 12 · 訪問量 55萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章