/* Demo of modified Lucas-Kanade optical flow algorithm. See the printf below */ #ifdef _CH_ #pragma package #endif #define CV_NO_BACKWARD_COMPATIBILITY #ifndef _EiC #include "cv.h" #include "highgui.h" #include #include #endif IplImage *image = 0, *grey = 0, *prev_grey = 0, *pyramid = 0, *prev_pyramid = 0, *swap_temp; int win_size = 10; const int MAX_COUNT = 500; CvPoint2D32f* points[2] = {0,0}, *swap_points; char* status = 0; int count = 0; int need_to_init = 0; int night_mode = 0; int flags = 0; int add_remove_pt = 0; CvPoint pt; void on_mouse( int event, int x, int y, int flags, void* param ) { if( !image ) return; if( image->origin ) y = image->height - y; if( event == CV_EVENT_LBUTTONDOWN ) { pt = cvPoint(x,y); add_remove_pt = 1; } } int main( int argc, char** argv ) { CvCapture* capture = 0; if( argc == 1 || (argc == 2 && strlen(argv[1]) == 1 && isdigit(argv[1][0]))) capture = cvCaptureFromCAM( argc == 2 ? argv[1][0] - '0' : 0 ); else if( argc == 2 ) capture = cvCaptureFromAVI( argv[1] ); if( !capture ) { fprintf(stderr,"Could not initialize capturing...\n"); return -1; } /* print a welcome message, and the OpenCV version */ printf ("Welcome to lkdemo, using OpenCV version %s (%d.%d.%d)\n", CV_VERSION, CV_MAJOR_VERSION, CV_MINOR_VERSION, CV_SUBMINOR_VERSION); printf( "Hot keys: \n" "\tESC - quit the program\n" "\tr - auto-initialize tracking\n" "\tc - delete all the points\n" "\tn - switch the \"night\" mode on/off\n" "To add/remove a feature point click it\n" ); cvNamedWindow( "LkDemo", 0 ); cvSetMouseCallback( "LkDemo", on_mouse, 0 ); for(;;) { IplImage* frame = 0; int i, k, c; frame = cvQueryFrame( capture ); if( !frame ) break; if( !image ) { /* allocate all the buffers */ image = cvCreateImage( cvGetSize(frame), 8, 3 ); image->origin = frame->origin; grey = cvCreateImage( cvGetSize(frame), 8, 1 ); prev_grey = cvCreateImage( cvGetSize(frame), 8, 1 ); pyramid = cvCreateImage( cvGetSize(frame), 8, 1 ); prev_pyramid = cvCreateImage( cvGetSize(frame), 8, 1 ); points[0] = (CvPoint2D32f*)cvAlloc(MAX_COUNT*sizeof(points[0][0])); points[1] = (CvPoint2D32f*)cvAlloc(MAX_COUNT*sizeof(points[0][0])); status = (char*)cvAlloc(MAX_COUNT); flags = 0; } cvCopy( frame, image, 0 ); cvCvtColor( image, grey, CV_BGR2GRAY ); if( night_mode ) cvZero( image ); if( need_to_init ) { /* automatic initialization */ IplImage* eig = cvCreateImage( cvGetSize(grey), 32, 1 ); IplImage* temp = cvCreateImage( cvGetSize(grey), 32, 1 ); double quality = 0.01; double min_distance = 10; count = MAX_COUNT; cvGoodFeaturesToTrack( grey, eig, temp, points[1], &count, quality, min_distance, 0, 3, 0, 0.04 ); cvFindCornerSubPix( grey, points[1], count, cvSize(win_size,win_size), cvSize(-1,-1), cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,20,0.03)); cvReleaseImage( &eig ); cvReleaseImage( &temp ); add_remove_pt = 0; } else if( count > 0 ) { cvCalcOpticalFlowPyrLK( prev_grey, grey, prev_pyramid, pyramid, points[0], points[1], count, cvSize(win_size,win_size), 3, status, 0, cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,20,0.03), flags ); flags |= CV_LKFLOW_PYR_A_READY; for( i = k = 0; i < count; i++ ) { if( add_remove_pt ) { double dx = pt.x - points[1][i].x; double dy = pt.y - points[1][i].y; if( dx*dx + dy*dy <= 25 ) { add_remove_pt = 0; continue; } } if( !status[i] ) continue; points[1][k++] = points[1][i]; cvCircle( image, cvPointFrom32f(points[1][i]), 3, CV_RGB(0,255,0), -1, 8,0); } count = k; } if( add_remove_pt && count < MAX_COUNT ) { points[1][count++] = cvPointTo32f(pt); cvFindCornerSubPix( grey, points[1] + count - 1, 1, cvSize(win_size,win_size), cvSize(-1,-1), cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,20,0.03)); add_remove_pt = 0; } CV_SWAP( prev_grey, grey, swap_temp ); CV_SWAP( prev_pyramid, pyramid, swap_temp ); CV_SWAP( points[0], points[1], swap_points ); need_to_init = 0; cvShowImage( "LkDemo", image ); c = cvWaitKey(10); if( (char)c == 27 ) break; switch( (char) c ) { case 'r': need_to_init = 1; break; case 'c': count = 0; break; case 'n': night_mode ^= 1; break; default: ; } } cvReleaseCapture( &capture ); cvDestroyWindow("LkDemo"); return 0; } #ifdef _EiC main(1,"lkdemo.c"); #endif