Beispiel #1
0
bool CascadeTrainI::createClassifier( const string& tempDir, 
                       const string& vecFname, const string& bgName,
                       int numPos, int numNeg, 
                       const TrainerPropertiesI *trainProps)
{
  CvCascadeClassifier classifier;
  int precalcValBufSize = 256,
      precalcIdxBufSize = 256;
  bool baseFormatSave = false;
  CvCascadeParams cascadeParams;
  cascadeParams.winSize.width = trainProps->windowSize.width;
  cascadeParams.winSize.height = trainProps->windowSize.height;
  CvCascadeBoostParams stageParams;
  Ptr<CvFeatureParams> featureParams[] = 
  { Ptr<CvFeatureParams>(new CvHaarFeatureParams),
    Ptr<CvFeatureParams>(new CvLBPFeatureParams),
    Ptr<CvFeatureParams>(new CvHOGFeatureParams)
  };
  cascadeParams.featureType = trainProps->featureType;
  stageParams.boost_type = trainProps->boost_type;

  bool res = classifier.train( tempDir,
                    vecFname,
                    bgName,
                    numPos, numNeg,
                    precalcValBufSize, precalcIdxBufSize,
                    trainProps->numStages,
                    cascadeParams,
                    *featureParams[cascadeParams.featureType],
                    stageParams,
                    baseFormatSave );  
  return res;
}
Beispiel #2
0
int main( int argc, char* argv[] )
{
    CvCascadeClassifier classifier;
    string cascadeDirName, vecName, bgName;
    int numPos    = 2000;
    int numNeg    = 1000;
    int numStages = 20;
    int numThreads = getNumThreads();
    int precalcValBufSize = 256,
        precalcIdxBufSize = 256;
    bool baseFormatSave = false;

    CvCascadeParams cascadeParams;
    CvCascadeBoostParams stageParams;
    Ptr<CvFeatureParams> featureParams[] = { makePtr<CvHaarFeatureParams>(),
                                             makePtr<CvLBPFeatureParams>(),
                                             makePtr<CvHOGFeatureParams>()
                                           };
    int fc = sizeof(featureParams)/sizeof(featureParams[0]);
    if( argc == 1 )
    {
        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;
        cout << "  [-numNeg <number_of_negative_samples = " << numNeg << ">]" << endl;
        cout << "  [-numStages <number_of_stages = " << numStages << ">]" << endl;
        cout << "  [-precalcValBufSize <precalculated_vals_buffer_size_in_Mb = " << precalcValBufSize << ">]" << endl;
        cout << "  [-precalcIdxBufSize <precalculated_idxs_buffer_size_in_Mb = " << precalcIdxBufSize << ">]" << endl;
        cout << "  [-baseFormatSave]" << endl;
        cout << "  [-numThreads <max_number_of_threads = " << numThreads << ">]" << endl;
        cascadeParams.printDefaults();
        stageParams.printDefaults();
        for( int fi = 0; fi < fc; fi++ )
            featureParams[fi]->printDefaults();
        return 0;
    }

    for( int i = 1; i < argc; i++ )
    {
        bool set = false;
        if( !strcmp( argv[i], "-data" ) )
        {
            cascadeDirName = argv[++i];
        }
        else if( !strcmp( argv[i], "-vec" ) )
        {
            vecName = argv[++i];
        }
        else if( !strcmp( argv[i], "-bg" ) )
        {
            bgName = argv[++i];
        }
        else if( !strcmp( argv[i], "-numPos" ) )
        {
            numPos = atoi( argv[++i] );
        }
        else if( !strcmp( argv[i], "-numNeg" ) )
        {
            numNeg = atoi( argv[++i] );
        }
        else if( !strcmp( argv[i], "-numStages" ) )
        {
            numStages = atoi( argv[++i] );
        }
        else if( !strcmp( argv[i], "-precalcValBufSize" ) )
        {
            precalcValBufSize = atoi( argv[++i] );
        }
        else if( !strcmp( argv[i], "-precalcIdxBufSize" ) )
        {
            precalcIdxBufSize = atoi( argv[++i] );
        }
        else if( !strcmp( argv[i], "-baseFormatSave" ) )
        {
            baseFormatSave = true;
        }
        else if( !strcmp( argv[i], "-numThreads" ) )
        {
          numThreads = atoi(argv[++i]);
        }
        else if ( cascadeParams.scanAttr( argv[i], argv[i+1] ) ) { i++; }
        else if ( stageParams.scanAttr( argv[i], argv[i+1] ) ) { i++; }
        else if ( !set )
        {
            for( int fi = 0; fi < fc; fi++ )
            {
                set = featureParams[fi]->scanAttr(argv[i], argv[i+1]);
                if ( !set )
                {
                    i++;
                    break;
                }
            }
        }
    }

    setNumThreads( numThreads );
    classifier.train( cascadeDirName,
                      vecName,
                      bgName,
                      numPos, numNeg,
                      precalcValBufSize, precalcIdxBufSize,
                      numStages,
                      cascadeParams,
                      *featureParams[cascadeParams.featureType],
                      stageParams,
                      baseFormatSave );
    return 0;
}
int main( int argc, char* argv[] )
{
    // переменные и классы
    CvCascadeClassifier classifier;     // from cascadeclassifier.h
    string cascadeDirName, vecName, bgName;
    int numPos    = 2000;			    // Number of positive samples used in training for every classifier stage. 
    int numNeg    = 1000;			    // Number of negative samples used in training for every classifier stage.
    int numStages = 20;			        // Number of cascade stages to be trained.
    int numThreads = getNumThreads();   // Maximum number of threads to use during training. Notice that the actual number of used 
                                        // threads may be lower, depending on your machine and compilation options.
                                        // Function getNumThreads() from opencv2/core.hpp 
    int precalcValBufSize = 1024,       // Size of buffer for precalculated feature values (in Mb).
        precalcIdxBufSize = 1024;       // Size of buffer for precalculated feature indices (in Mb). The more memory you have the 
                                        // faster the training process.
    bool baseFormatSave = false;        // This argument is actual in case of Haar-like features. If it is specified, the cascade will 
                                        // be saved in the old format.
    double acceptanceRatioBreakValue = -1.0; // This argument is used to determine how precise your model should keep learning and 
                                             // when to stop. A good guideline is to train not further than 10e-5, to ensure 
                                             // the model does not overtrain on your training data. By default this value is 
                                             // set to -1 to disable this feature.
    
    // Cascade parameters:
    CvCascadeParams cascadeParams;  // from cascadeclassifier.h
    // здесь устанавливаются стандартные параметры каскада: 
    //
    // CvCascadeParams::CvCascadeParams() : stageType( defaultStageType ),  // Type of stages. Only boosted classifier are supported as a stage type at the moment.
    //                                                                      // -stageType <BOOST(default)>
    //                                      featureType( defaultFeatureType ),  // Type of features: HAAR - Haar-like features, 
    //                                                                          //                   LBP - local binary patterns.
    //                                                                          // -featureType<{HAAR(default), LBP}>
    //                                      winSize( cvSize(24, 24) )   // Size of training samples (in pixels). Must have exactly 
    //                                                                  // the same values as used during training samples creation 
    //                                                                  // (opencv_createsamples utility).
    // {
    //      name = CC_CASCADE_PARAMS;
    // }

    // Boosted classifer parameters:
    CvCascadeBoostParams stageParams; // from cascadeclassifier.h <-- boost.h
    // CvCascadeBoostParams(        int _boostType,       // Type of boosted classifiers: 
    //                                                    // DAB - Discrete AdaBoost, 
    //                                                    // RAB - Real AdaBoost, 
    //                                                    // LB - LogitBoost, 
    //                                                    // GAB - Gentle AdaBoost.
    //                                                    // -bt <{DAB, RAB, LB, GAB(default)}>
    //                              float _minHitRate,    // Minimal desired hit rate for each stage of the classifier. Overall hit rate may be estimated 
    //                                                    // as (min_hit_rate\^number_of_stages).
    //                                                    // -minHitRate <min_hit_rate>
    //                              float _maxFalseAlarm, // Maximal desired false alarm rate for each stage of the classifier. Overall false alarm rate 
    //                                                    // may be estimated as (max_false_alarm_rate\^number_of_stages).
    //                                                    // -maxFalseAlarmRate <max_false_alarm_rate>  
    //                              double _weightTrimRate, // Specifies whether trimming should be used and its weight. A decent choice is 0.95.
    //                                                      // -weightTrimRate <weight_trim_rate>
    //                              int _maxDepth,          // Maximal depth of a weak tree. A decent choice is 1, that is case of stumps.
    //                                                      // -maxDepth <max_depth_of_weak_tree>
    //                              int _maxWeakCount );    // Maximal count of weak trees for every cascade stage. The boosted classifier (stage) will 
    //                                                      // have so many weak trees (<=maxWeakCount), as needed to achieve the given -maxFalseAlarmRate.
    //                                                      // -maxWeakCount <max_weak_tree_count>

    
    // вот здесь непонятно, массив из фичей Haar, LBP и HOG! 
    Ptr<CvFeatureParams> featureParams[] = { makePtr<CvHaarFeatureParams>(),
                                             makePtr<CvLBPFeatureParams>(),
                                             makePtr<CvHOGFeatureParams>()
                                           };
     
    int fc = sizeof(featureParams)/sizeof(featureParams[0]); // вычисление размера массива
    
    // здесь проиходит вывод справочной инфы, если не были переданы параметры
    if( argc == 1 )
    {
        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;
        cout << "  [-numNeg <number_of_negative_samples = " << numNeg << ">]" << endl;
        cout << "  [-numStages <number_of_stages = " << numStages << ">]" << endl;
        cout << "  [-precalcValBufSize <precalculated_vals_buffer_size_in_Mb = " << precalcValBufSize << ">]" << endl;
        cout << "  [-precalcIdxBufSize <precalculated_idxs_buffer_size_in_Mb = " << precalcIdxBufSize << ">]" << endl;
        cout << "  [-baseFormatSave]" << endl;
        cout << "  [-numThreads <max_number_of_threads = " << numThreads << ">]" << endl;
        cout << "  [-acceptanceRatioBreakValue <value> = " << acceptanceRatioBreakValue << ">]" << endl;
        cascadeParams.printDefaults();
        stageParams.printDefaults();
        for( int fi = 0; fi < fc; fi++ )
            featureParams[fi]->printDefaults();
        return 0;
    }
    
    // распознавание аргументов командной строки Common arguments: 
    // -data <cascade_dir_name>
    // -vec <vec_file_name>
    // -bg <background_file_name>
    // -numPos <number_of_positive_samples>
    // -numNeg <number_of_negative_samples>
    // -numStages <number_of_stages>
    // -precalcValBufSize <precalculated_vals_buffer_size_in_Mb>
    // -precalcIdxBufSize <precalculated_idxs_buffer_size_in_Mb>
    // -baseFormatSave
    // -numThreads <max_number_of_threads>
    // -acceptanceRatioBreakValue <break_value>
    
    for( int i = 1; i < argc; i++ )
    {
        bool set = false;
        if( !strcmp( argv[i], "-data" ) )
        {
            cascadeDirName = argv[++i];
        }
        else if( !strcmp( argv[i], "-vec" ) )
        {
            vecName = argv[++i];
        }
        else if( !strcmp( argv[i], "-bg" ) )
        {
            bgName = argv[++i];
        }
        else if( !strcmp( argv[i], "-numPos" ) )
        {
            numPos = atoi( argv[++i] );
        }
        else if( !strcmp( argv[i], "-numNeg" ) )
        {
            numNeg = atoi( argv[++i] );
        }
        else if( !strcmp( argv[i], "-numStages" ) )
        {
            numStages = atoi( argv[++i] );
        }
        else if( !strcmp( argv[i], "-precalcValBufSize" ) )
        {
            precalcValBufSize = atoi( argv[++i] );
        }
        else if( !strcmp( argv[i], "-precalcIdxBufSize" ) )
        {
            precalcIdxBufSize = atoi( argv[++i] );
        }
        else if( !strcmp( argv[i], "-baseFormatSave" ) )
        {
            baseFormatSave = true;
        }
        else if( !strcmp( argv[i], "-numThreads" ) )
        {
          numThreads = atoi(argv[++i]);
        }
        else if( !strcmp( argv[i], "-acceptanceRatioBreakValue" ) )
        {
          acceptanceRatioBreakValue = atof(argv[++i]);
        }
        // распознавание аргументов командной строки Cascade parameters: 
        else if ( cascadeParams.scanAttr( argv[i], argv[i+1] ) ) { i++; }
        // распознавание аргументов командной строки Boosted classifer parameters: 
        else if ( stageParams.scanAttr( argv[i], argv[i+1] ) ) { i++; }
        // что-то происходит, если ещё какие параметры идут, возможно, Haar-like feature parameters:
        // -mode <BASIC (default) | CORE | ALL>
        // Selects the type of Haar features set used in training. BASIC use only upright features, while ALL uses 
        // the full set of upright and 45 degree rotated feature set. See [86] for more details.
        else if ( !set )
        {
            for( int fi = 0; fi < fc; fi++ )
            {
                set = featureParams[fi]->scanAttr(argv[i], argv[i+1]);
                if ( !set )
                {
                    i++;
                    break;
                }
            }
        }
    }
    
    // set max_number_of_threads
    // Maximum number of threads to use during training. Notice that the actual number of used 
    // threads may be lower, depending on your machine and compilation options.
    setNumThreads( numThreads );
    
    // метод train определён в cascadeclassifier.h, он тренирует классификатор и сохраняет его в xml-file
    // After the traincascade application has finished its work, the trained cascade will be saved 
    // in cascade.xml file in the folder, which was passed as -data parameter. Other files in this folder 
    // are created for the case of interrupted training, so you may delete them after completion of training.
    classifier.train( cascadeDirName,
                      vecName,
                      bgName,
                      numPos, numNeg,
                      precalcValBufSize, precalcIdxBufSize,
                      numStages,
                      cascadeParams,
                      *featureParams[cascadeParams.featureType],
                      stageParams,
                      baseFormatSave,
                      acceptanceRatioBreakValue );
    return 0;
}