Mercurial Hosting > traffic-intelligence
view c/optical-flow.cpp @ 12:ff5403319cec
optical flow demo working
author | Nicolas Saunier <nico@confins.net> |
---|---|
date | Wed, 11 Nov 2009 23:25:23 -0500 |
parents | e77e2fd69b02 |
children | 3ead4bcd001c |
line wrap: on
line source
#include "cvutils.hpp" #include "utils.hpp" #include "opencv/cv.h" #include "opencv/highgui.h" #include <iostream> #include <ctime> using namespace std; void videoTiming(CvCapture* inputVideo) { IplImage* frame = cvQueryFrame(inputVideo); //IplImage* bwFrame = allocateImage(frame->width, frame->height, IPL_DEPTH_8U, 1); int frameNum = 0; time_t seconds; time_t t0 = time(NULL); while (frame) { frameNum = ::goToFrameNum(inputVideo, frameNum, frameNum+1000); seconds = time(NULL)-t0; cout << frameNum << " " << seconds << endl; } } int main(int argc, char *argv[]) { //cout << "Hello World" << endl; CvCapture *inputVideo = 0; if (argc == 1) inputVideo = cvCreateCameraCapture(-1); else inputVideo = cvCaptureFromFile(argv[1]); int frameNum = 0; cvNamedWindow("Optical Flow", CV_WINDOW_AUTOSIZE); // allocate space for pyramids IplImage* frame = cvQueryFrame(inputVideo); CvSize frameSize = cvSize(frame->width, frame->height); IplImage* frame1_1C = ::allocateImage(frameSize, IPL_DEPTH_8U, 1); cvConvertImage(frame, frame1_1C); IplImage *frame1 = ::allocateImage(frameSize, IPL_DEPTH_8U, 3); cvConvertImage(frame, frame1); frame = cvQueryFrame(inputVideo); IplImage* frame2_1C = ::allocateImage(frameSize, IPL_DEPTH_8U, 1); cvConvertImage(frame, frame2_1C); IplImage *eig_image = ::allocateImage(frameSize, IPL_DEPTH_32F, 1); IplImage *temp_image = ::allocateImage(frameSize, IPL_DEPTH_32F, 1); int nFeatures = 1000; CvPoint2D32f frame1_features[1000]; CvPoint2D32f frame2_features[1000]; char optical_flow_found_feature[1000]; float optical_flow_feature_error[1000]; CvSize optical_flow_window = cvSize(3,3); CvTermCriteria optical_flow_termination_criteria = cvTermCriteria( CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 20, .3 ); IplImage* pyramid1 = ::allocateImage(frameSize, IPL_DEPTH_8U, 1); IplImage* pyramid2 = ::allocateImage(frameSize, IPL_DEPTH_8U, 1); int pressedKey = '?'; while (frame && !::interruptionKey(pressedKey)) { cvGoodFeaturesToTrack(frame1_1C, eig_image, temp_image, frame1_features, &nFeatures, .01, .01, NULL); cvCalcOpticalFlowPyrLK(frame1_1C, frame2_1C, pyramid1, pyramid2, frame1_features, frame2_features, nFeatures, optical_flow_window, 5, optical_flow_found_feature, optical_flow_feature_error, optical_flow_termination_criteria, 0 ); for(int i = 0; i < nFeatures; i++) { /* If Pyramidal Lucas Kanade didn't really find the feature, skip it. */ if ( optical_flow_found_feature[i] == 0 ) continue; int line_thickness; line_thickness = 1; /* CV_RGB(red, green, blue) is the red, green, and blue components * of the color you want, each out of 255. */ CvScalar line_color; line_color = CV_RGB(255,0,0); /* Let's make the flow field look nice with arrows. */ /* The arrows will be a bit too short for a nice visualization because of the high framerate * (ie: there's not much motion between the frames). So let's lengthen them by a factor of 3. */ CvPoint p,q; p.x = (int) frame1_features[i].x; p.y = (int) frame1_features[i].y; q.x = (int) frame2_features[i].x; q.y = (int) frame2_features[i].y; double angle; angle = atan2( (double) p.y - q.y, (double) p.x - q.x ); double hypotenuse; hypotenuse = sqrt( square(p.y - q.y) + square(p.x - q.x) ); /* Here we lengthen the arrow by a factor of three. */ q.x = (int) (p.x - 3 * hypotenuse * cos(angle)); q.y = (int) (p.y - 3 * hypotenuse * sin(angle)); /* Now we draw the main line of the arrow. */ /* "frame1" is the frame to draw on. * "p" is the point where the line begins. * "q" is the point where the line stops. * "CV_AA" means antialiased drawing. * "0" means no fractional bits in the center cooridinate or radius. */ cvLine( frame1, p, q, line_color, line_thickness, CV_AA, 0 ); /* Now draw the tips of the arrow. I do some scaling so that the * tips look proportional to the main line of the arrow. */ p.x = (int) (q.x + 9 * cos(angle + pi / 4)); p.y = (int) (q.y + 9 * sin(angle + pi / 4)); cvLine( frame1, p, q, line_color, line_thickness, CV_AA, 0 ); p.x = (int) (q.x + 9 * cos(angle - pi / 4)); p.y = (int) (q.y + 9 * sin(angle - pi / 4)); cvLine( frame1, p, q, line_color, line_thickness, CV_AA, 0 ); } cvShowImage("Optical Flow", frame1); //cvWaitKey(5); pressedKey = cvWaitKey(5); frame = cvQueryFrame(inputVideo); frameNum++; cout << frameNum << endl; cvCopy(frame2_1C, frame1_1C); cvCopy(pyramid2, pyramid1); cvConvertImage(frame, frame2_1C); cvConvertImage(frame, frame1); } return 1; }