Update the trunk to the OpenCV's CVS (2008-07-14)
[opencv] / samples / c / lkdemo.c
1 /* Demo of modified Lucas-Kanade optical flow algorithm.
2    See the printf below */
3
4 #ifdef _CH_
5 #pragma package <opencv>
6 #endif
7
8 #ifndef _EiC
9 #include "cv.h"
10 #include "highgui.h"
11 #include <stdio.h>
12 #include <ctype.h>
13 #endif
14
15 IplImage *image = 0, *grey = 0, *prev_grey = 0, *pyramid = 0, *prev_pyramid = 0, *swap_temp;
16
17 int win_size = 10;
18 const int MAX_COUNT = 500;
19 CvPoint2D32f* points[2] = {0,0}, *swap_points;
20 char* status = 0;
21 int count = 0;
22 int need_to_init = 0;
23 int night_mode = 0;
24 int flags = 0;
25 int add_remove_pt = 0;
26 CvPoint pt;
27
28
29 void on_mouse( int event, int x, int y, int flags, void* param )
30 {
31     if( !image )
32         return;
33
34     if( image->origin )
35         y = image->height - y;
36
37     if( event == CV_EVENT_LBUTTONDOWN )
38     {
39         pt = cvPoint(x,y);
40         add_remove_pt = 1;
41     }
42 }
43
44
45 int main( int argc, char** argv )
46 {
47     CvCapture* capture = 0;
48     
49     if( argc == 1 || (argc == 2 && strlen(argv[1]) == 1 && isdigit(argv[1][0])))
50         capture = cvCaptureFromCAM( argc == 2 ? argv[1][0] - '0' : 0 );
51     else if( argc == 2 )
52         capture = cvCaptureFromAVI( argv[1] );
53
54     if( !capture )
55     {
56         fprintf(stderr,"Could not initialize capturing...\n");
57         return -1;
58     }
59
60     /* print a welcome message, and the OpenCV version */
61     printf ("Welcome to lkdemo, using OpenCV version %s (%d.%d.%d)\n",
62             CV_VERSION,
63             CV_MAJOR_VERSION, CV_MINOR_VERSION, CV_SUBMINOR_VERSION);
64
65     printf( "Hot keys: \n"
66             "\tESC - quit the program\n"
67             "\tr - auto-initialize tracking\n"
68             "\tc - delete all the points\n"
69             "\tn - switch the \"night\" mode on/off\n"
70             "To add/remove a feature point click it\n" );
71
72     cvNamedWindow( "LkDemo", 0 );
73     cvSetMouseCallback( "LkDemo", on_mouse, 0 );
74
75     for(;;)
76     {
77         IplImage* frame = 0;
78         int i, k, c;
79
80         frame = cvQueryFrame( capture );
81         if( !frame )
82             break;
83
84         if( !image )
85         {
86             /* allocate all the buffers */
87             image = cvCreateImage( cvGetSize(frame), 8, 3 );
88             image->origin = frame->origin;
89             grey = cvCreateImage( cvGetSize(frame), 8, 1 );
90             prev_grey = cvCreateImage( cvGetSize(frame), 8, 1 );
91             pyramid = cvCreateImage( cvGetSize(frame), 8, 1 );
92             prev_pyramid = cvCreateImage( cvGetSize(frame), 8, 1 );
93             points[0] = (CvPoint2D32f*)cvAlloc(MAX_COUNT*sizeof(points[0][0]));
94             points[1] = (CvPoint2D32f*)cvAlloc(MAX_COUNT*sizeof(points[0][0]));
95             status = (char*)cvAlloc(MAX_COUNT);
96             flags = 0;
97         }
98
99         cvCopy( frame, image, 0 );
100         cvCvtColor( image, grey, CV_BGR2GRAY );
101
102         if( night_mode )
103             cvZero( image );
104         
105         if( need_to_init )
106         {
107             /* automatic initialization */
108             IplImage* eig = cvCreateImage( cvGetSize(grey), 32, 1 );
109             IplImage* temp = cvCreateImage( cvGetSize(grey), 32, 1 );
110             double quality = 0.01;
111             double min_distance = 10;
112
113             count = MAX_COUNT;
114             cvGoodFeaturesToTrack( grey, eig, temp, points[1], &count,
115                                    quality, min_distance, 0, 3, 0, 0.04 );
116             cvFindCornerSubPix( grey, points[1], count,
117                 cvSize(win_size,win_size), cvSize(-1,-1),
118                 cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,20,0.03));
119             cvReleaseImage( &eig );
120             cvReleaseImage( &temp );
121
122             add_remove_pt = 0;
123         }
124         else if( count > 0 )
125         {
126             cvCalcOpticalFlowPyrLK( prev_grey, grey, prev_pyramid, pyramid,
127                 points[0], points[1], count, cvSize(win_size,win_size), 3, status, 0,
128                 cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,20,0.03), flags );
129             flags |= CV_LKFLOW_PYR_A_READY;
130             for( i = k = 0; i < count; i++ )
131             {
132                 if( add_remove_pt )
133                 {
134                     double dx = pt.x - points[1][i].x;
135                     double dy = pt.y - points[1][i].y;
136
137                     if( dx*dx + dy*dy <= 25 )
138                     {
139                         add_remove_pt = 0;
140                         continue;
141                     }
142                 }
143                 
144                 if( !status[i] )
145                     continue;
146                 
147                 points[1][k++] = points[1][i];
148                 cvCircle( image, cvPointFrom32f(points[1][i]), 3, CV_RGB(0,255,0), -1, 8,0);
149             }
150             count = k;
151         }
152
153         if( add_remove_pt && count < MAX_COUNT )
154         {
155             points[1][count++] = cvPointTo32f(pt);
156             cvFindCornerSubPix( grey, points[1] + count - 1, 1,
157                 cvSize(win_size,win_size), cvSize(-1,-1),
158                 cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,20,0.03));
159             add_remove_pt = 0;
160         }
161
162         CV_SWAP( prev_grey, grey, swap_temp );
163         CV_SWAP( prev_pyramid, pyramid, swap_temp );
164         CV_SWAP( points[0], points[1], swap_points );
165         need_to_init = 0;
166         cvShowImage( "LkDemo", image );
167
168         c = cvWaitKey(10);
169         if( (char)c == 27 )
170             break;
171         switch( (char) c )
172         {
173         case 'r':
174             need_to_init = 1;
175             break;
176         case 'c':
177             count = 0;
178             break;
179         case 'n':
180             night_mode ^= 1;
181             break;
182         default:
183             ;
184         }
185     }
186
187     cvReleaseCapture( &capture );
188     cvDestroyWindow("LkDemo");
189
190     return 0;
191 }
192
193 #ifdef _EiC
194 main(1,"lkdemo.c");
195 #endif