Mercurial Hosting > traffic-intelligence
changeset 137:445e773c9be3
created the parameter structure to parse parameters (bug remaining)
author | Nicolas Saunier <nicolas.saunier@polymtl.ca> |
---|---|
date | Fri, 19 Aug 2011 01:35:45 -0400 |
parents | 0f790de9437e |
children | c1b260b48d2a |
files | c/Makefile c/Motion.cpp c/Parameters.cpp c/feature-based-tracking.cpp c/tracking.cfg include/Parameters.hpp |
diffstat | 6 files changed, 216 insertions(+), 81 deletions(-) [+] |
line wrap: on
line diff
--- a/c/Makefile Thu Aug 18 22:25:21 2011 -0400 +++ b/c/Makefile Fri Aug 19 01:35:45 2011 -0400 @@ -10,7 +10,8 @@ LDFLAGS = -lm LDFLAGS += -lTrajectoryManagementAndAnalysis -lsqlite3 -#LDFLAGS += -lboost_program_options-mt -lboost_filesystem-mt -lboost_system-mt -lboost_unit_test_framework-mt +LDFLAGS += -lboost_program_options-mt +# -lboost_filesystem-mt -lboost_system-mt -lboost_unit_test_framework-mt #LDFLAGS += -lfltk CFLAGS = -Wall -W -Wextra @@ -64,7 +65,7 @@ test: echo "coucou $(HOME)" -feature-based-tracking: feature-based-tracking.o cvutils.o Motion.o +feature-based-tracking: feature-based-tracking.o cvutils.o Motion.o Parameters.o $(CXX) $(CFLAGS) $(LIBS) $^ -o $(BUILD_DIR)/$@ $(LDFLAGS) track-features.o: track-features.cpp
--- a/c/Motion.cpp Thu Aug 18 22:25:21 2011 -0400 +++ b/c/Motion.cpp Fri Aug 19 01:35:45 2011 -0400 @@ -17,7 +17,7 @@ unsigned int nPositions = positions.size(); if (nPositions > nDisplacements) { float disp = 0; - for (int i=0; i<nDisplacements; i++) + for (unsigned int i=0; i<nDisplacements; i++) disp += displacementDistances[nPositions-2-i]; result = disp > minTotalFeatureDisplacement; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c/Parameters.cpp Fri Aug 19 01:35:45 2011 -0400 @@ -0,0 +1,110 @@ +#include "Parameters.hpp" + +#include <boost/program_options.hpp> + +#include <iostream> +#include <fstream> + +namespace po = boost::program_options; +using namespace std; + +KLTFeatureTrackingParameters::KLTFeatureTrackingParameters(const int argc, char* argv[]) { + std::string configurationFilename; + po::options_description onlyCmdLine("Command line only"); + po::options_description cmdLineAndFile("Command line and configuration file"); + + // configuration filename + onlyCmdLine.add_options() + ("config-file", po::value<string>(&configurationFilename)->default_value("tracking.cfg"), "configuration file") + ; + + po::positional_options_description p; + p.add("config-file", 1); + + // common to cnnfiguration and command line + cmdLineAndFile.add_options() + ("help,h", "displays this help message") + ("video-filename", po::value<string>(&videoFilename), "filename of the video to process") + ("database-filename", po::value<string>(&databaseFilename), "filename of the database where results are saved") + ("homography-filename", po::value<string>(&homographyFilename), "filename of the homography matrix") + ("mask-filename", po::value<string>(&maskFilename), "filename of the mask image (where features are detected)") + ("load-features", po::value<bool>(&loadFeatures), "load features from database") + ("display", po::value<bool>(&display), "display trajectories on the video") + ("video-fps", po::value<float>(&videoFPS), "original video frame rate") + ("frame1", po::value<int>(&frame1), "first frame to process") + ("nframes", po::value<int>(&nFrames), "number of frame to process") + // feature tracking + ("max-nfeatures", po::value<int>(&maxNFeatures), "maximum number of features added at each frame") + ("feature-quality", po::value<float>(&featureQuality), "quality level of the good features to track") + ("min-feature-distanceklt", po::value<float>(&minFeatureDistanceKLT), "minimum distance between features") + ("window-size", po::value<int>(&windowSize), "size of the search window at each pyramid level") + ("use-harris-detector", po::value<bool>(&useHarrisDetector), "use of Harris corner detector") + ("k", po::value<float>(&k), "k parameter to detect good features to track (OpenCV)") + ("pyramid-level", po::value<int>(&pyramidLevel), "maximal pyramid level in the feature tracking algorithm") + ("ndisplacements", po::value<unsigned int>(&nDisplacements), "number of displacement to test minimum feature motion") + ("min-feature-displacement", po::value<float>(&minFeatureDisplacement), "minimum displacement to keep features") + ("acceleration-bound", po::value<float>(&accelerationBound), "maximum feature acceleration") + ("deviation-bound", po::value<float>(&deviationBound), "maximum feature deviation") + ("nframes-smoothing", po::value<int>(&nFramesSmoothing), "number of frames to smooth positions (half window)") + ("max-number-iterations", po::value<int>(&maxNumberTrackingIterations), "maximum number of iterations to stop feature tracking") + ("min-tracking-error", po::value<float>(&minTrackingError), "minimum error to reach to stop feature tracking") + ("min-feature-time", po::value<unsigned int>(&minFeatureTime), "minimum length of a feature (number of frames) to consider a feature for grouping") + ("mm-connection-distance", po::value<float>(&mmConnectionDistance), "connection distance in feature grouping") + ("mm-segmentation-distance", po::value<float>(&mmSegmentationDistance), "segmentation distance in feature grouping") + ("max-distance", po::value<float>(&maxDistance), "maximum distance between features for grouping") + ("min-velocity-cosine", po::value<float>(&minVelocityCosine), "minimum cosine of the angle between the velocity vectors for grouping") + ("min-nfeatures-group", po::value<int>(&minNFeaturesPerGroup), "minimum average number of features per frame to create a vehicle hypothesis") + ; + // ("max-uturn-cosine", po::value<float>(&maxUTurnCosine), "maximum cosine value to detect U-turn") + // ("nframes-avoid-uturn", po::value<int>(&nFramesAvoidUTurn), "number of frames over which a feature should not make a U-turn") + + + po::options_description cmdLine; + cmdLine.add(onlyCmdLine).add(cmdLineAndFile); + try { + po::variables_map vm; + store(po::command_line_parser(argc, argv). + options(cmdLine).positional(p).allow_unregistered().run(), vm); + notify(vm); + + if (vm.count("help")) { + cout << cmdLine << endl; + // cout << "Positional options:"; + // for (unsigned int i=0; i<p.max_total_count(); i++) + // cout << " " << p.name_for_position(i); + // cout << endl; + exit(0); + } + cout << "Using configuration file " << configurationFilename << endl; + + ifstream configurationFile(configurationFilename.c_str()); + store(po::parse_config_file(configurationFile, cmdLineAndFile), vm); + notify(vm); + + parameterDescription = getParameterDescription(cmdLine, vm); + } catch(exception& e) { + cout << e.what() << endl; + } +} + +string KLTFeatureTrackingParameters::getParameterDescription(po::options_description& options, const po::variables_map& vm, const string& separator /* = " " */) const { + stringstream stream; + vector<boost::shared_ptr<po::option_description> > optionsVec = options.options(); + for (unsigned int i=0; i<optionsVec.size(); ++i) { + boost::any value = vm[optionsVec[i]->long_name()].value(); + if (value.type() == typeid(bool)) + stream << boost::any_cast<bool>(value) << separator; + else if (value.type() == typeid(int)) + stream << boost::any_cast<int>(value) << separator; + else if (value.type() == typeid(unsigned int)) + stream << boost::any_cast<unsigned int>(value) << separator; + else if (value.type() == typeid(float)) + stream << boost::any_cast<float>(value) << separator; + else if (value.type() == typeid(string)) + stream << boost::any_cast<string>(value) << separator; + else + cerr << "the type of the option variable " << i << " is not int, float or string." << endl; + } + + return stream.str(); +}
--- a/c/feature-based-tracking.cpp Thu Aug 18 22:25:21 2011 -0400 +++ b/c/feature-based-tracking.cpp Fri Aug 19 01:35:45 2011 -0400 @@ -60,56 +60,56 @@ VideoCapture capture; Mat frame, currentFrameBW, previousFrameBW; - KLTFeatureTrackingParameters params; - params.display = true; - params.frame1 = 0; - params.nFrames = -1; - params.maxNFeatures = 1000; - params.featureQuality = 0.1; - params.minFeatureDistanceKLT = 3; - params.windowSize = 3; - params.useHarrisDetector = false; - params.k = 0.4; - //GoodFeaturesToTrackDetector detector(params.maxNFeatures, params.featureQuality, params.minFeatureDistanceKLT, params.windowSize, params.useHarrisDetector, params.k); + KLTFeatureTrackingParameters params(argc, argv); + cout << params.parameterDescription << endl; + // params.display = true; + // params.frame1 = 0; + // params.nFrames = -1; + // params.maxNFeatures = 1000; + // params.featureQuality = 0.1; + // params.minFeatureDistanceKLT = 3; + // params.windowSize = 3; + // params.useHarrisDetector = false; + // params.k = 0.4; + // //GoodFeaturesToTrackDetector detector(params.maxNFeatures, params.featureQuality, params.minFeatureDistanceKLT, params.windowSize, params.useHarrisDetector, params.k); - params.pyramidLevel = 3; - params.nDisplacements = 3; - params.minFeatureDisplacement = 0.05; - float minTotalFeatureDisplacement = params.nDisplacements*params.minFeatureDisplacement; + // params.pyramidLevel = 3; + // params.nDisplacements = 3; + // params.minFeatureDisplacement = 0.05; - params.maxNumberTrackingIterations = 20; // 30 - params.minTrackingError = 0.3; // 0.01 - params.derivLambda = 0.5; - params.minFeatureTime = 20; + // params.maxNumberTrackingIterations = 20; // 30 + // params.minTrackingError = 0.3; // 0.01 + // params.minFeatureTime = 20; + float minTotalFeatureDisplacement = params.nDisplacements*params.minFeatureDisplacement; Size window = Size(params.windowSize, params.windowSize); BruteForceMatcher<Hamming> descMatcher; vector<DMatch> matches; Size videoSize; - if( argc == 1 || (argc == 2 && strlen(argv[1]) == 1 && isdigit(argv[1][0]))) // if no parameter or number parameter - capture.open(argc == 2 ? argv[1][0] - '0' : 0); - else if( argc >= 2 ) - { - capture.open(argv[1]); - if( capture.isOpened() ) - videoSize = Size(capture.get(CV_CAP_PROP_FRAME_WIDTH), capture.get(CV_CAP_PROP_FRAME_HEIGHT)); - cout << "Video " << argv[1] << - ": width=" << videoSize.width << - ", height=" << videoSize.height << - ", nframes=" << capture.get(CV_CAP_PROP_FRAME_COUNT) << endl; - if( argc > 2 && isdigit(argv[2][0]) ) // could be used to reach first frame, dumping library messages to log file (2> /tmp/log.txt) - { - sscanf(argv[2], "%d", ¶ms.frame1); - cout << "seeking to frame #" << params.frame1 << endl; - //cap.set(CV_CAP_PROP_POS_FRAMES, pos); - for (int i=0; i<params.frame1; i++) - capture >> frame; - } - } + // if( argc == 1 || (argc == 2 && strlen(argv[1]) == 1 && isdigit(argv[1][0]))) // if no parameter or number parameter + // capture.open(argc == 2 ? argv[1][0] - '0' : 0); + // else if( argc >= 2 ) + // { + // capture.open(argv[1]); + // if( capture.isOpened() ) + // videoSize = Size(capture.get(CV_CAP_PROP_FRAME_WIDTH), capture.get(CV_CAP_PROP_FRAME_HEIGHT)); + // cout << "Video " << argv[1] << + // ": width=" << videoSize.width << + // ", height=" << videoSize.height << + // ", nframes=" << capture.get(CV_CAP_PROP_FRAME_COUNT) << endl; + // if( argc > 2 && isdigit(argv[2][0]) ) // could be used to reach first frame, dumping library messages to log file (2> /tmp/log.txt) + // { + // sscanf(argv[2], "%d", ¶ms.frame1); + // cout << "seeking to frame #" << params.frame1 << endl; + // //cap.set(CV_CAP_PROP_POS_FRAMES, pos); + // for (int i=0; i<params.frame1; i++) + // capture >> frame; + // } + // } - // capture.open(atoi(argv[1])); + capture.open(params.videoFilename); if (!capture.isOpened()) { //help(argv); @@ -149,7 +149,7 @@ if (!prevPts.empty()) { //::keyPoints2Points(prevKpts, prevPts); currPts.clear(); - calcOpticalFlowPyrLK(previousFrameBW, currentFrameBW, prevPts, currPts, status, errors, window, params.pyramidLevel, TermCriteria(3 /*static_cast<int>(TermCriteria::COUNT)+static_cast<int>(TermCriteria::EPS)*/, params.maxNumberTrackingIterations, params.minTrackingError), params.derivLambda, 0); // OPTFLOW_USE_INITIAL_FLOW + calcOpticalFlowPyrLK(previousFrameBW, currentFrameBW, prevPts, currPts, status, errors, window, params.pyramidLevel, TermCriteria(3 /*static_cast<int>(TermCriteria::COUNT)+static_cast<int>(TermCriteria::EPS)*/, params.maxNumberTrackingIterations, params.minTrackingError), 0.5 /* unused */, 0); // OPTFLOW_USE_INITIAL_FLOW vector<Point2f> trackedPts; vector<FeaturePointMatch>::iterator iter = featurePointMatches.begin();
--- a/c/tracking.cfg Thu Aug 18 22:25:21 2011 -0400 +++ b/c/tracking.cfg Fri Aug 19 01:35:45 2011 -0400 @@ -1,50 +1,64 @@ -# video file to process: videoFilenamePrefix -video-filename = carrefour.avi -# original video frame rate: videoFPS +# filename of the video to process +video-filename = ~/Research/Data/minnesota/Rice-and-University-12_50.avi +# filename of the database where results are saved +database-filename = ~/Research/Data/minnesota/results.sqlite +# filename of the homography matrix +homography-filename = ~/Research/Data/minnesota/Rice-and-University-12_50-homography.txt +# filename of the mask image (where features are detected) +mask-filename = ~/Research/Data/minnesota/Rice-and-University-12_50-mask.png +# load features from database +load-features = false +# display trajectories on the video +display = false +# original video frame rate video-fps = 29.97 -# number of digits of precision for all measurements derived from video: measurementPrecision -measurement-precision = 3 -# first frame to process: frame1 +# number of digits of precision for all measurements derived from video +# measurement-precision = 3 +# first frame to process frame1 = 0 -# number of frame to process: nFrames +# number of frame to process nframes = -1 # feature tracking -# maximum number of tracked features (> 500): maxNFeatures +# maximum number of features added at each frame max-nfeatures = 1000 -# quality level of the good features to track: featureQuality +# quality level of the good features to track feature-quality = 0.1 -# minimum distance between features: minFeatureDistanceKLT -min-feature-distance = 5 -# size of the search window at each pyramid level: windowSize +# minimum distance between features +min-feature-distanceklt = 5 +# size of the search window at each pyramid level window-size = 7 -# maximal pyramid level in the feature tracking algorithm: pyramidLevel +# use of Harris corner detector +use-harris-detector = false +# k parameter to detect good features to track (OpenCV) +k = 0.4 +# maximal pyramid level in the feature tracking algorithm pyramid-level = 5 -# number of frames to compute the feature displacement: nFramesDisplacement -nframes-displacement = 3 -# minimum displacement to keep features: minFeatureDisplacement +# number of displacement to test minimum feature motion +ndisplacements = 3 +# minimum displacement to keep features min-feature-displacement = 0.05 -# maximum feature acceleration: accelerationBound +# maximum feature acceleration acceleration-bound = 3 -# maximum feature deviation: deviationBound +# maximum feature deviation deviation-bound = 0.6 -# number of frames to smooth positions (half window): nFramesSmoothing +# number of frames to smooth positions (half window) nframes-smoothing = 5 -# number of frames to compute velocities: nFramesVelocity -nframes-velocity = 5 -# maximum number of iterations to stop feature tracking: maxNumberTrackingIterations +# number of frames to compute velocities +#nframes-velocity = 5 +# maximum number of iterations to stop feature tracking max-number-iterations = 20 -# minimum error to reach to stop feature tracking: minTrackingError +# minimum error to reach to stop feature tracking min-tracking-error = 0.3 -# minimum length of a feature (number of frames) to consider a feature for grouping: minFeatureTime +# minimum length of a feature (number of frames) to consider a feature for grouping min-feature-time = 20 # Min Max similarity parameters (Beymer et al. method) -# connection distance in feature grouping: mmConnectionDistance +# connection distance in feature grouping mm-connection-distance = 3.75 -# segmentation distance in feature grouping: mmSegmentationDistance +# segmentation distance in feature grouping mm-segmentation-distance = 1.5 -# maximum distance between features for grouping: maxDistance +# maximum distance between features for grouping max-distance = 5 -# minimum cosine of the angle between the velocity vectors for grouping: minVelocityCosine +# minimum cosine of the angle between the velocity vectors for grouping min-velocity-cosine = 0.8 -# minimum average number of features per frame to create a vehicle hypothesis: minNFeaturesPerGroup +# minimum average number of features per frame to create a vehicle hypothesis min-nfeatures-group = 3
--- a/include/Parameters.hpp Thu Aug 18 22:25:21 2011 -0400 +++ b/include/Parameters.hpp Fri Aug 19 01:35:45 2011 -0400 @@ -5,14 +5,22 @@ #include <string> -struct KLTFeatureTrackingParameters { - /// whether to load saved features, or compute them - bool loadFeatures; +namespace boost{ + namespace program_options { + class options_description; + class variables_map; + } +} +struct KLTFeatureTrackingParameters { std::string videoFilename; - int videoFPS; - int measurementPrecision; + std::string databaseFilename; + std::string homographyFilename; + std::string maskFilename; + bool loadFeatures; bool display; + float videoFPS; + // int measurementPrecision; int frame1; int nFrames; // feature tracking @@ -28,10 +36,9 @@ float accelerationBound; float deviationBound; int nFramesSmoothing; - int nFramesVelocity; + //int nFramesVelocity; int maxNumberTrackingIterations; float minTrackingError; - float derivLambda; unsigned int minFeatureTime; float mmConnectionDistance; float mmSegmentationDistance; @@ -39,10 +46,13 @@ float minVelocityCosine; int minNFeaturesPerGroup; - //KLTFeatureTrackingParameters(const int argc, char* argv[]); + std::string parameterDescription; + + KLTFeatureTrackingParameters(const int argc, char* argv[]); //KLTFeatureTrackingParameters(bool loadFeatures, std::string videoFilename, int videoFPS, int measurementPrecision, int frame1, int nFrames, int maxNFeatures, float featureQuality, float minFeatureDistanceKLT, int windowSize, int pyramidLevel, int nDisplacements, float minFeatureDisplacement, float accelerationBound, float deviationBound, int nFramesSmoothing, int nFramesVelocity, int maxNumberTrackingIterations, float minTrackingError, int minFeatureTime, float mmConnectionDistance, float mmSegmentationDistance, float maxDistance, float minVelocityCosine, int minNFeaturesPerGroup); + std::string getParameterDescription(boost::program_options::options_description& options, const boost::program_options::variables_map& vm, const std::string& separator = " ") const; }; #endif