void setup() { stream.setLabelsForAllDimensions({"x", "y", "z"}); useInputStream(stream); DTW dtw(false, true, null_rej); dtw.enableTrimTrainingData(true, 0.1, 75); pipeline.setClassifier(dtw); pipeline.addPostProcessingModule(ClassLabelTimeoutFilter(timeout)); usePipeline(pipeline); registerTuneable( null_rej, 0.1, 5.0, "Variability", "How different from the training data a new gesture can be and " "still be considered the same gesture. The higher the number, the " "more different it can be.", [](double new_null_rej) { pipeline.getClassifier()->setNullRejectionCoeff(new_null_rej); pipeline.getClassifier()->recomputeNullRejectionThresholds(); }); registerTuneable( timeout, 1, 3000, "Timeout", "How long (in milliseconds) to wait after recognizing a " "gesture before recognizing another one.", [](double new_timeout) { ClassLabelTimeoutFilter* filter = dynamic_cast<ClassLabelTimeoutFilter*>( pipeline.getPostProcessingModule(0)); assert(filter != nullptr); filter->setTimeoutDuration(new_timeout); }); }
void updateAlwaysPickSomething(bool new_val) { pipeline.getClassifier()->enableNullRejection(!new_val); }
void updateVariability(double new_null_rej) { pipeline.getClassifier()->setNullRejectionCoeff(new_null_rej); pipeline.getClassifier()->recomputeNullRejectionThresholds(); }
bool combineModels( CommandLineParser &parser ){ infoLog << "Combining models..." << endl; string directoryPath = ""; string modelFilename = ""; if( !parser.get("data-dir",directoryPath) ){ errorLog << "Failed to parse data-directory from command line! You can set the data-directory using the --data-dir option." << endl; printUsage(); return false; } //Get the filename if( !parser.get("model-filename",modelFilename) ){ errorLog << "Failed to parse filename from command line! You can set the model filename using the --model." << endl; printUsage(); return false; } Vector< string > files; infoLog << "- Parsing data directory: " << directoryPath << endl; //Parse the directory to get all the csv files if( !Util::parseDirectory( directoryPath, ".grt", files ) ){ errorLog << "Failed to parse data directory!" << endl; return false; } RandomForests forest; //Used to validate the random forest type GestureRecognitionPipeline *mainPipeline = NULL; // Points to the first valid pipeline that all the models will be merged to Vector< GestureRecognitionPipeline* > pipelineBuffer; //Stores the pipeline for each file that is loaded unsigned int inputVectorSize = 0; //Set to zero to mark we haven't loaded any models yet const unsigned int numFiles = files.getSize(); bool mainPipelineSet = false; bool combineModelsSuccessful = false; pipelineBuffer.reserve( numFiles ); //Loop over the files, load them, and add valid random forest pipelines to the pipelineBuffer so they can be combined with the mainPipeline for(unsigned int i=0; i<numFiles; i++){ infoLog << "- Loading model " << files[i] << ". File " << i+1 << " of " << numFiles << endl; GestureRecognitionPipeline *pipeline = new GestureRecognitionPipeline; if( pipeline->load( files[i] ) ){ infoLog << "- Pipeline loaded. Number of input dimensions: " << pipeline->getInputVectorDimensionsSize() << endl; if( pipelineBuffer.size() == 0 ){ inputVectorSize = pipeline->getInputVectorDimensionsSize(); } if( pipeline->getInputVectorDimensionsSize() != inputVectorSize ){ warningLog << "- Pipeline " << i+1 << " input vector size does not match the size of the first pipeline!" << endl; }else{ Classifier *classifier = pipeline->getClassifier(); if( classifier ){ if( classifier->getClassifierType() == forest.getClassifierType() ){ //Validate the classifier is a random forest if( !mainPipelineSet ){ mainPipelineSet = true; mainPipeline = pipeline; }else pipelineBuffer.push_back( pipeline ); }else{ warningLog << "- Pipeline " << i+1 << " does not contain a random forest classifer! Classifier type: " << classifier->getClassifierType() << endl; } } } }else{ warningLog << "- WARNING: Failed to load model from file: " << files[i] << endl; } } if( mainPipelineSet ){ //Combine the random forest models with the main pipeline model const unsigned int numPipelines = pipelineBuffer.getSize(); RandomForests *mainForest = mainPipeline->getClassifier< RandomForests >(); for(unsigned int i=0; i<numPipelines; i++){ infoLog << "- Combing model " << i+1 << " of " << numPipelines << " with main model..." << endl; RandomForests *f = pipelineBuffer[i]->getClassifier< RandomForests >(); if( !mainForest->combineModels( *f ) ){ warningLog << "- WARNING: Failed to combine model " << i+1 << " with the main model!" << endl; } } if( mainPipeline->getTrained() ){ infoLog << "- Saving combined pipeline to file..." << endl; combineModelsSuccessful = mainPipeline->save( modelFilename ); } }else{ errorLog << "Failed to combined models, no models were loaded!" << endl; } //Cleanup the pipeline buffer for(unsigned int i=0; i<pipelineBuffer.getSize(); i++){ delete pipelineBuffer[i]; pipelineBuffer[i] = NULL; } return combineModelsSuccessful; }