comparison c/feature-based-tracking.cpp @ 127:d19d6e63dd77

simple feature tracking and drawing working
author Nicolas Saunier <nicolas.saunier@polymtl.ca>
date Wed, 17 Aug 2011 01:25:13 -0400
parents 28907fde9855
children 536510f60854
comparison
equal deleted inserted replaced
126:336926453b28 127:d19d6e63dd77
1 //#include "Feature.hpp" 1 //#include "Feature.hpp"
2 #include "Parameters.hpp" 2 #include "Parameters.hpp"
3 #include "cvutils.hpp"
3 #include "utils.hpp" 4 #include "utils.hpp"
4 5
5 #include "src/Trajectory.h" 6 #include "src/Trajectory.h"
6 7
8 #include "opencv2/core/core.hpp"
7 #include "opencv2/highgui/highgui.hpp" 9 #include "opencv2/highgui/highgui.hpp"
8 //#include "opencv2/imgproc/imgproc.hpp" 10 //#include "opencv2/imgproc/imgproc.hpp"
9 #include "opencv2/features2d/features2d.hpp" 11 #include "opencv2/features2d/features2d.hpp"
10 12
11 #include <boost/shared_ptr.hpp> 13 #include <boost/shared_ptr.hpp>
23 { 25 {
24 Point2f pt_new = query[matches[i].queryIdx].pt; 26 Point2f pt_new = query[matches[i].queryIdx].pt;
25 Point2f pt_old = train[matches[i].trainIdx].pt; 27 Point2f pt_old = train[matches[i].trainIdx].pt;
26 Point2f dist = pt_new - pt_old; 28 Point2f dist = pt_new - pt_old;
27 if (norm(dist) < 20) { 29 if (norm(dist) < 20) {
28 cv::line(img, pt_new, pt_old, Scalar(125, 255, 125), 1); 30 line(img, pt_new, pt_old, Scalar(125, 255, 125), 1);
29 cv::circle(img, pt_new, 2, Scalar(255, 0, 125), 1); 31 circle(img, pt_old, 2, Scalar(255, 0, 125), 1);
30 } 32 }
31 } 33 }
32 } 34 }
33 35
36 void drawOpticalFlow(const vector<Point2f>& prevPts, const vector<Point2f>& currPts, const vector<uchar> status, Mat& img) {
37 for (unsigned int i=0; i<status.size(); i++) {
38 if (status[i]) {
39 line(img, prevPts[i], currPts[i], Scalar(125, 255, 125), 1);
40 circle(img, prevPts[i], 2, Scalar(255, 0, 125), 1);
41 }
42 }
43 }
44
34 int main(int argc, char *argv[]) { 45 int main(int argc, char *argv[]) {
35 //vector<TrajectoryPoint2f> features; 46 //vector<TrajectoryPoint2f> features;
36 47
37 BriefDescriptorExtractor brief(32); 48 BriefDescriptorExtractor brief(32);
38 const int DESIRED_FTRS = 500; 49 const int DESIRED_FTRS = 500;
39 //shared_ptr<FeatureDetector> detector = shared_ptr<FeatureDetector>(new GridAdaptedFeatureDetector(new FastFeatureDetector(10, true), DESIRED_FTRS, 4, 4)); 50 //shared_ptr<FeatureDetector> detector = shared_ptr<FeatureDetector>(new GridAdaptedFeatureDetector(new FastFeatureDetector(10, true), DESIRED_FTRS, 4, 4));
40 GridAdaptedFeatureDetector detector(new FastFeatureDetector(10, true), DESIRED_FTRS, 4, 4); 51 //GridAdaptedFeatureDetector detector(new FastFeatureDetector(10, true), DESIRED_FTRS, 4, 4);
41 52
42 VideoCapture capture; 53 VideoCapture capture;
43 Mat frame, display; 54 Mat frame, currentFrameBW, previousFrameBW;
44 55
45 KLTFeatureTrackingParameters params; 56 KLTFeatureTrackingParameters params;
46 params.frame1 = 0; 57 params.frame1 = 0;
47 params.nFrames = -1; 58 params.nFrames = -1;
48 // TODO ajouter klt paremeters, reprendre code de opencvfeaturetracker 59 params.maxNFeatures = 1000;
49 //GoodFeaturesToTrackDetector detector(Params.max_nfeatures, Params.feature_quality, Params.min_feature_distance_klt, Params.window_size, Params.useHarrisDetector_GoodFeaturesToTrackDetector, Params.k_GoodFeaturesToTrackDetector); 60 params.featureQuality = 0.1;
50 // search descriptor_match.h 61 params.minFeatureDistanceKLT = 3;
62 params.windowSize = 3;
63 params.useHarrisDetector = false;
64 params.k = 0.4;
65 GoodFeaturesToTrackDetector detector(params.maxNFeatures, params.featureQuality, params.minFeatureDistanceKLT, params.windowSize, params.useHarrisDetector, params.k);
66
67 params.pyramidLevel = 3;
68 params.maxNumberTrackingIterations = 20; // 30
69 params.minTrackingError = 0.3; // 0.01
70 params.derivLambda = 0.5;
71 Size window = Size(params.windowSize, params.windowSize);
51 72
52 BruteForceMatcher<Hamming> descMatcher; 73 BruteForceMatcher<Hamming> descMatcher;
53 vector<DMatch> matches; 74 vector<DMatch> matches;
54 75
55 if( argc == 1 || (argc == 2 && strlen(argv[1]) == 1 && isdigit(argv[1][0]))) // if no parameter or number parameter 76 if( argc == 1 || (argc == 2 && strlen(argv[1]) == 1 && isdigit(argv[1][0]))) // if no parameter or number parameter
79 cout << "capture device " << argv[1] << " failed to open!" << endl; 100 cout << "capture device " << argv[1] << " failed to open!" << endl;
80 return 1; 101 return 1;
81 } 102 }
82 103
83 vector<KeyPoint> prevKpts, currKpts; 104 vector<KeyPoint> prevKpts, currKpts;
105 vector<Point2f> prevPts, currPts;
106 vector<uchar> status;
107 vector<float> errors;
108 Mat prevDesc, currDesc;
84 109
85 Mat gray;
86
87 Mat prevDesc, currDesc;
88 // TODO structure de donnee paires pointeur trajectory, numero de keypoint 110 // TODO structure de donnee paires pointeur trajectory, numero de keypoint
89 int key = '?'; 111 int key = '?';
90 for (int frameNum = 0; ((params.frame1+frameNum < params.nFrames) || (params.nFrames < 0)) && !::interruptionKey(key); frameNum++) { 112 for (int frameNum = 0; ((params.frame1+frameNum < params.nFrames) || (params.nFrames < 0)) && !::interruptionKey(key); frameNum++) {
91 capture >> frame; 113 capture >> frame;
92 cout << capture.get(CV_CAP_PROP_POS_FRAMES) << endl; 114 cout << capture.get(CV_CAP_PROP_POS_FRAMES) << endl;
93 while (frame.empty()) 115 while (frame.empty())
94 capture >> frame;//break; 116 capture >> frame;//break;
95 117
96 cvtColor(frame, gray, CV_RGB2GRAY); 118 cvtColor(frame, currentFrameBW, CV_RGB2GRAY);
97 119
98 detector.detect(gray, currKpts); 120 detector.detect(currentFrameBW, currKpts);
99 //cout << currKpts.size() << " kpts" << endl; 121 //cout << currKpts.size() << " kpts" << endl;
100 122
101 brief.compute(gray, currKpts, currDesc); //Compute brief descriptors at each keypoint location 123 brief.compute(currentFrameBW, currKpts, currDesc); //Compute brief descriptors at each keypoint location
102 124
103 //display = frame.clone();
104 if (!prevKpts.empty()) { 125 if (!prevKpts.empty()) {
105 cout << matches.size() << " matches" << endl; 126 ::keyPoints2Points(prevKpts, prevPts);
106 descMatcher.match(currDesc, prevDesc, matches); 127 currPts.clear();
107 cout << matches.size() << " matches" << endl; 128 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
129 drawOpticalFlow(prevPts, currPts, status, frame);
130
131 // cout << matches.size() << " matches" << endl;
132 // descMatcher.match(currDesc, prevDesc, matches);
133 // cout << matches.size() << " matches" << endl;
108 drawMatchesRelative(prevKpts, currKpts, matches, frame); 134 drawMatchesRelative(prevKpts, currKpts, matches, frame);
109 //drawMatches(frame, prevKpts, frame, currKpts, matches, display);//, Scalar::all(-1), Scalar::all(-1), vector<vector<char> >(), DrawMatchesFlags::DRAW_OVER_OUTIMG); 135 //drawMatches(frame, prevKpts, frame, currKpts, matches, display);//, Scalar::all(-1), Scalar::all(-1), vector<vector<char> >(), DrawMatchesFlags::DRAW_OVER_OUTIMG);
110 } 136 }
111 137
112 imshow("frame", frame); 138 imshow("frame", frame);
139 previousFrameBW = currentFrameBW.clone();
113 prevKpts = currKpts; 140 prevKpts = currKpts;
114 currDesc.copyTo(prevDesc); 141 currDesc.copyTo(prevDesc);
115 key = waitKey(0); 142 key = waitKey(2);
116 } 143 }
117 144
118 return 0; 145 return 0;
119 } 146 }
120 147