mirror of https://github.com/opencv/opencv.git
Open Source Computer Vision Library
https://opencv.org/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
197 lines
5.5 KiB
197 lines
5.5 KiB
/* Demo of modified Lucas-Kanade optical flow algorithm. |
|
See the printf below */ |
|
|
|
#ifdef _CH_ |
|
#pragma package <opencv> |
|
#endif |
|
|
|
#define CV_NO_BACKWARD_COMPATIBILITY |
|
|
|
#ifndef _EiC |
|
#include "cv.h" |
|
#include "highgui.h" |
|
#include <stdio.h> |
|
#include <ctype.h> |
|
#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
|
|
|