• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "opencv2/video/tracking.hpp"
2 #include "opencv2/imgproc/imgproc.hpp"
3 #include "opencv2/videoio/videoio.hpp"
4 #include "opencv2/highgui/highgui.hpp"
5 
6 #include <iostream>
7 #include <ctype.h>
8 
9 using namespace cv;
10 using namespace std;
11 
help()12 static void help()
13 {
14     // print a welcome message, and the OpenCV version
15     cout << "\nThis is a demo of Lukas-Kanade optical flow lkdemo(),\n"
16             "Using OpenCV version " << CV_VERSION << endl;
17     cout << "\nIt uses camera by default, but you can provide a path to video as an argument.\n";
18     cout << "\nHot keys: \n"
19             "\tESC - quit the program\n"
20             "\tr - auto-initialize tracking\n"
21             "\tc - delete all the points\n"
22             "\tn - switch the \"night\" mode on/off\n"
23             "To add/remove a feature point click it\n" << endl;
24 }
25 
26 Point2f point;
27 bool addRemovePt = false;
28 
onMouse(int event,int x,int y,int,void *)29 static void onMouse( int event, int x, int y, int /*flags*/, void* /*param*/ )
30 {
31     if( event == EVENT_LBUTTONDOWN )
32     {
33         point = Point2f((float)x, (float)y);
34         addRemovePt = true;
35     }
36 }
37 
main(int argc,char ** argv)38 int main( int argc, char** argv )
39 {
40     help();
41 
42     VideoCapture cap;
43     TermCriteria termcrit(TermCriteria::COUNT|TermCriteria::EPS,20,0.03);
44     Size subPixWinSize(10,10), winSize(31,31);
45 
46     const int MAX_COUNT = 500;
47     bool needToInit = false;
48     bool nightMode = false;
49 
50     if( argc == 1 || (argc == 2 && strlen(argv[1]) == 1 && isdigit(argv[1][0])))
51         cap.open(argc == 2 ? argv[1][0] - '0' : 0);
52     else if( argc == 2 )
53         cap.open(argv[1]);
54 
55     if( !cap.isOpened() )
56     {
57         cout << "Could not initialize capturing...\n";
58         return 0;
59     }
60 
61     namedWindow( "LK Demo", 1 );
62     setMouseCallback( "LK Demo", onMouse, 0 );
63 
64     Mat gray, prevGray, image, frame;
65     vector<Point2f> points[2];
66 
67     for(;;)
68     {
69         cap >> frame;
70         if( frame.empty() )
71             break;
72 
73         frame.copyTo(image);
74         cvtColor(image, gray, COLOR_BGR2GRAY);
75 
76         if( nightMode )
77             image = Scalar::all(0);
78 
79         if( needToInit )
80         {
81             // automatic initialization
82             goodFeaturesToTrack(gray, points[1], MAX_COUNT, 0.01, 10, Mat(), 3, 0, 0.04);
83             cornerSubPix(gray, points[1], subPixWinSize, Size(-1,-1), termcrit);
84             addRemovePt = false;
85         }
86         else if( !points[0].empty() )
87         {
88             vector<uchar> status;
89             vector<float> err;
90             if(prevGray.empty())
91                 gray.copyTo(prevGray);
92             calcOpticalFlowPyrLK(prevGray, gray, points[0], points[1], status, err, winSize,
93                                  3, termcrit, 0, 0.001);
94             size_t i, k;
95             for( i = k = 0; i < points[1].size(); i++ )
96             {
97                 if( addRemovePt )
98                 {
99                     if( norm(point - points[1][i]) <= 5 )
100                     {
101                         addRemovePt = false;
102                         continue;
103                     }
104                 }
105 
106                 if( !status[i] )
107                     continue;
108 
109                 points[1][k++] = points[1][i];
110                 circle( image, points[1][i], 3, Scalar(0,255,0), -1, 8);
111             }
112             points[1].resize(k);
113         }
114 
115         if( addRemovePt && points[1].size() < (size_t)MAX_COUNT )
116         {
117             vector<Point2f> tmp;
118             tmp.push_back(point);
119             cornerSubPix( gray, tmp, winSize, Size(-1,-1), termcrit);
120             points[1].push_back(tmp[0]);
121             addRemovePt = false;
122         }
123 
124         needToInit = false;
125         imshow("LK Demo", image);
126 
127         char c = (char)waitKey(10);
128         if( c == 27 )
129             break;
130         switch( c )
131         {
132         case 'r':
133             needToInit = true;
134             break;
135         case 'c':
136             points[0].clear();
137             points[1].clear();
138             break;
139         case 'n':
140             nightMode = !nightMode;
141             break;
142         }
143 
144         std::swap(points[1], points[0]);
145         cv::swap(prevGray, gray);
146     }
147 
148     return 0;
149 }
150