Mercurial > hg > nsaunier > traffic-intelligence
comparison c/feature-based-tracking.cpp @ 147:0089fb29cd26
added projection of points and reprojection for display
| author | Nicolas Saunier <nicolas.saunier@polymtl.ca> |
|---|---|
| date | Tue, 30 Aug 2011 13:38:31 -0400 |
| parents | 7150427c665e |
| children | 668710d4c773 |
comparison
equal
deleted
inserted
replaced
| 146:7150427c665e | 147:0089fb29cd26 |
|---|---|
| 51 FeaturePointMatch(FeatureTrajectoryPtr _feature, const int& _pointNum): | 51 FeaturePointMatch(FeatureTrajectoryPtr _feature, const int& _pointNum): |
| 52 feature(_feature), pointNum(_pointNum) {} | 52 feature(_feature), pointNum(_pointNum) {} |
| 53 }; | 53 }; |
| 54 | 54 |
| 55 inline void saveFeatures(vector<FeatureTrajectoryPtr>& features, TrajectoryDBAccess<Point2f>& db, const string& positionsTableName, const string& velocitiesTableName, const unsigned int& minNFeatures = 0) { | 55 inline void saveFeatures(vector<FeatureTrajectoryPtr>& features, TrajectoryDBAccess<Point2f>& db, const string& positionsTableName, const string& velocitiesTableName, const unsigned int& minNFeatures = 0) { |
| 56 /// \todo smoothing | |
| 56 if (features.size() >= minNFeatures) { | 57 if (features.size() >= minNFeatures) { |
| 57 BOOST_FOREACH(FeatureTrajectoryPtr f, features) f->write(db, positionsTableName, velocitiesTableName); | 58 BOOST_FOREACH(FeatureTrajectoryPtr f, features) f->write(db, positionsTableName, velocitiesTableName); |
| 58 features.clear(); | 59 features.clear(); |
| 59 } | 60 } |
| 60 } | 61 } |
| 68 Mat frame, currentFrameBW, previousFrameBW; | 69 Mat frame, currentFrameBW, previousFrameBW; |
| 69 | 70 |
| 70 KLTFeatureTrackingParameters params(argc, argv); | 71 KLTFeatureTrackingParameters params(argc, argv); |
| 71 cout << params.parameterDescription << endl; | 72 cout << params.parameterDescription << endl; |
| 72 | 73 |
| 73 Mat m = ::loadMat(params.homographyFilename, " "); | 74 Mat homography = ::loadMat(params.homographyFilename, " "); |
| 74 //cout << m << endl; | 75 Mat invHomography; |
| 76 if (params.display && !homography.empty()) | |
| 77 invHomography = homography.inv(); | |
| 75 | 78 |
| 76 float minTotalFeatureDisplacement = params.nDisplacements*params.minFeatureDisplacement; | 79 float minTotalFeatureDisplacement = params.nDisplacements*params.minFeatureDisplacement; |
| 77 Size window = Size(params.windowSize, params.windowSize); | 80 Size window = Size(params.windowSize, params.windowSize); |
| 78 | 81 |
| 79 BruteForceMatcher<Hamming> descMatcher; | 82 BruteForceMatcher<Hamming> descMatcher; |
| 117 // //help(argv); | 120 // //help(argv); |
| 118 // cout << "capture device " << argv[1] << " failed to open!" << endl; | 121 // cout << "capture device " << argv[1] << " failed to open!" << endl; |
| 119 // return 1; | 122 // return 1; |
| 120 // } | 123 // } |
| 121 | 124 |
| 122 // mask | |
| 123 Mat mask = imread(params.maskFilename, 0); | 125 Mat mask = imread(params.maskFilename, 0); |
| 124 if (mask.empty()) | 126 if (mask.empty()) |
| 125 mask = Mat::ones(videoSize, CV_8UC1); | 127 mask = Mat::ones(videoSize, CV_8UC1); |
| 126 | 128 |
| 127 // database | |
| 128 boost::shared_ptr<TrajectoryDBAccess<Point2f> > trajectoryDB = boost::shared_ptr<TrajectoryDBAccess<Point2f> >(new TrajectoryDBAccessList<Point2f>()); | 129 boost::shared_ptr<TrajectoryDBAccess<Point2f> > trajectoryDB = boost::shared_ptr<TrajectoryDBAccess<Point2f> >(new TrajectoryDBAccessList<Point2f>()); |
| 129 //TrajectoryDBAccess<Point2f>* trajectoryDB = new TrajectoryDBAccessBlob<Point2f>(); | 130 //TrajectoryDBAccess<Point2f>* trajectoryDB = new TrajectoryDBAccessBlob<Point2f>(); |
| 130 trajectoryDB->connect(params.databaseFilename.c_str()); | 131 trajectoryDB->connect(params.databaseFilename.c_str()); |
| 131 trajectoryDB->createTable("positions"); | 132 trajectoryDB->createTable("positions"); |
| 132 trajectoryDB->createTable("velocities"); | 133 trajectoryDB->createTable("velocities"); |
| 169 vector<FeaturePointMatch>::iterator iter = featurePointMatches.begin(); | 170 vector<FeaturePointMatch>::iterator iter = featurePointMatches.begin(); |
| 170 while (iter != featurePointMatches.end()) { | 171 while (iter != featurePointMatches.end()) { |
| 171 bool deleteFeature = false; | 172 bool deleteFeature = false; |
| 172 | 173 |
| 173 if (status[iter->pointNum]) { | 174 if (status[iter->pointNum]) { |
| 174 iter->feature->addPoint(frameNum, currPts[iter->pointNum]); | 175 iter->feature->addPoint(frameNum, currPts[iter->pointNum], homography); |
| 175 | 176 |
| 176 deleteFeature |= iter->feature->smallDisplacement(params.nDisplacements, minTotalFeatureDisplacement) | 177 deleteFeature |= iter->feature->smallDisplacement(params.nDisplacements, minTotalFeatureDisplacement) |
| 177 || !iter->feature->motionSmooth(params.accelerationBound, params.deviationBound); | 178 || !iter->feature->motionSmooth(params.accelerationBound, params.deviationBound); |
| 178 if (deleteFeature) | 179 if (deleteFeature) |
| 179 iter->feature->shorten(); | 180 iter->feature->shorten(); |
| 182 | 183 |
| 183 if (deleteFeature) { | 184 if (deleteFeature) { |
| 184 if (iter->feature->length() >= params.minFeatureTime) { | 185 if (iter->feature->length() >= params.minFeatureTime) { |
| 185 iter->feature->setId(savedFeatureId); | 186 iter->feature->setId(savedFeatureId); |
| 186 savedFeatureId++; | 187 savedFeatureId++; |
| 187 /// \todo smoothing | |
| 188 //iter->feature->write(*trajectoryDB); | |
| 189 lostFeatures.push_back(iter->feature); | 188 lostFeatures.push_back(iter->feature); |
| 190 } | 189 } |
| 191 iter = featurePointMatches.erase(iter); | 190 iter = featurePointMatches.erase(iter); |
| 192 } else { | 191 } else { |
| 193 trackedPts.push_back(currPts[iter->pointNum]); | 192 trackedPts.push_back(currPts[iter->pointNum]); |
| 199 assert(currPts.size() == featurePointMatches.size()); | 198 assert(currPts.size() == featurePointMatches.size()); |
| 200 saveFeatures(lostFeatures, *trajectoryDB, "positions", "velocities"); | 199 saveFeatures(lostFeatures, *trajectoryDB, "positions", "velocities"); |
| 201 | 200 |
| 202 if (params.display) { | 201 if (params.display) { |
| 203 BOOST_FOREACH(FeaturePointMatch fp, featurePointMatches) | 202 BOOST_FOREACH(FeaturePointMatch fp, featurePointMatches) |
| 204 fp.feature->draw(frame, Colors::red()); | 203 fp.feature->draw(frame, invHomography, Colors::red()); |
| 205 } | 204 } |
| 206 //drawOpticalFlow(prevPts, currPts, status, frame); | 205 //drawOpticalFlow(prevPts, currPts, status, frame); |
| 207 | 206 |
| 208 // cout << matches.size() << " matches" << endl; | 207 // cout << matches.size() << " matches" << endl; |
| 209 // descMatcher.match(currDesc, prevDesc, matches); | 208 // descMatcher.match(currDesc, prevDesc, matches); |
| 217 for (int j=MAX(0, currPts[n].x-params.minFeatureDistanceKLT); j<MIN(videoSize.width, currPts[n].x+params.minFeatureDistanceKLT+1); j++) | 216 for (int j=MAX(0, currPts[n].x-params.minFeatureDistanceKLT); j<MIN(videoSize.width, currPts[n].x+params.minFeatureDistanceKLT+1); j++) |
| 218 for (int i=MAX(0, currPts[n].y-params.minFeatureDistanceKLT); i<MIN(videoSize.height, currPts[n].y+params.minFeatureDistanceKLT+1); i++) | 217 for (int i=MAX(0, currPts[n].y-params.minFeatureDistanceKLT); i<MIN(videoSize.height, currPts[n].y+params.minFeatureDistanceKLT+1); i++) |
| 219 featureMask.at<uchar>(i,j)=0; | 218 featureMask.at<uchar>(i,j)=0; |
| 220 goodFeaturesToTrack(currentFrameBW, newPts, params.maxNFeatures, params.featureQuality, params.minFeatureDistanceKLT, featureMask, params.windowSize, params.useHarrisDetector, params.k); | 219 goodFeaturesToTrack(currentFrameBW, newPts, params.maxNFeatures, params.featureQuality, params.minFeatureDistanceKLT, featureMask, params.windowSize, params.useHarrisDetector, params.k); |
| 221 BOOST_FOREACH(Point2f p, newPts) { //for (unsigned int i=0; i<newPts.size(); i++) { | 220 BOOST_FOREACH(Point2f p, newPts) { //for (unsigned int i=0; i<newPts.size(); i++) { |
| 222 FeatureTrajectoryPtr f = FeatureTrajectoryPtr(new FeatureTrajectory(frameNum, p)); | 221 FeatureTrajectoryPtr f = FeatureTrajectoryPtr(new FeatureTrajectory(frameNum, p, homography)); |
| 223 featurePointMatches.push_back(FeaturePointMatch(f, currPts.size())); | 222 featurePointMatches.push_back(FeaturePointMatch(f, currPts.size())); |
| 224 currPts.push_back(p); | 223 currPts.push_back(p); |
| 225 } | 224 } |
| 226 // currPts.insert(currPts.end(), newPts.begin(), newPts.end()); | 225 // currPts.insert(currPts.end(), newPts.begin(), newPts.end()); |
| 227 //::keyPoints2Points(currKpts, currPts, false); | 226 //::keyPoints2Points(currKpts, currPts, false); |
