Mercurial Hosting > traffic-intelligence
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 |