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