Mercurial > hg > nsaunier > traffic-intelligence
comparison 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 |
comparison
equal
deleted
inserted
replaced
| 11:e77e2fd69b02 | 12:ff5403319cec |
|---|---|
| 1 #include "cvutils.hpp" | 1 #include "cvutils.hpp" |
| 2 #include "utils.hpp" | |
| 2 | 3 |
| 3 #include "opencv/cv.h" | 4 #include "opencv/cv.h" |
| 4 #include "opencv/highgui.h" | 5 #include "opencv/highgui.h" |
| 5 | 6 |
| 6 #include <iostream> | 7 #include <iostream> |
| 7 #include <ctime> | 8 #include <ctime> |
| 8 | 9 |
| 9 using namespace std; | 10 using namespace std; |
| 10 | 11 |
| 11 | 12 void videoTiming(CvCapture* inputVideo) { |
| 12 int main(int argc, char *argv[]) { | |
| 13 //cout << "Hello World" << endl; | |
| 14 | |
| 15 CvCapture *inputVideo = cvCaptureFromFile(argv[1]); | |
| 16 | |
| 17 IplImage* frame = cvQueryFrame(inputVideo); | 13 IplImage* frame = cvQueryFrame(inputVideo); |
| 18 //IplImage* bwFrame = allocateImage(frame->width, frame->height, IPL_DEPTH_8U, 1); | 14 //IplImage* bwFrame = allocateImage(frame->width, frame->height, IPL_DEPTH_8U, 1); |
| 19 | 15 |
| 20 int frameNum = 0; | 16 int frameNum = 0; |
| 21 time_t seconds; | 17 time_t seconds; |
| 22 time_t t0 = time(NULL); | 18 time_t t0 = time(NULL); |
| 23 while (frame) { | 19 while (frame) { |
| 24 ::goToFrameNum(capture, frameNum, frameNum+1000); | 20 frameNum = ::goToFrameNum(inputVideo, frameNum, frameNum+1000); |
| 25 seconds = time(NULL)-t0; | 21 seconds = time(NULL)-t0; |
| 26 | 22 |
| 27 cout << frameNum << " " << seconds << endl; | 23 cout << frameNum << " " << seconds << endl; |
| 24 } | |
| 25 } | |
| 28 | 26 |
| 29 frameNum+=1000; | 27 int main(int argc, char *argv[]) { |
| 28 //cout << "Hello World" << endl; | |
| 29 | |
| 30 CvCapture *inputVideo = 0; | |
| 31 if (argc == 1) | |
| 32 inputVideo = cvCreateCameraCapture(-1); | |
| 33 else | |
| 34 inputVideo = cvCaptureFromFile(argv[1]); | |
| 35 | |
| 36 int frameNum = 0; | |
| 37 cvNamedWindow("Optical Flow", CV_WINDOW_AUTOSIZE); | |
| 38 | |
| 39 // allocate space for pyramids | |
| 40 IplImage* frame = cvQueryFrame(inputVideo); | |
| 41 CvSize frameSize = cvSize(frame->width, frame->height); | |
| 42 | |
| 43 IplImage* frame1_1C = ::allocateImage(frameSize, IPL_DEPTH_8U, 1); | |
| 44 cvConvertImage(frame, frame1_1C); | |
| 45 | |
| 46 IplImage *frame1 = ::allocateImage(frameSize, IPL_DEPTH_8U, 3); | |
| 47 cvConvertImage(frame, frame1); | |
| 48 | |
| 49 frame = cvQueryFrame(inputVideo); | |
| 50 | |
| 51 IplImage* frame2_1C = ::allocateImage(frameSize, IPL_DEPTH_8U, 1); | |
| 52 cvConvertImage(frame, frame2_1C); | |
| 53 | |
| 54 IplImage *eig_image = ::allocateImage(frameSize, IPL_DEPTH_32F, 1); | |
| 55 IplImage *temp_image = ::allocateImage(frameSize, IPL_DEPTH_32F, 1); | |
| 56 | |
| 57 int nFeatures = 1000; | |
| 58 CvPoint2D32f frame1_features[1000]; | |
| 59 | |
| 60 CvPoint2D32f frame2_features[1000]; | |
| 61 | |
| 62 char optical_flow_found_feature[1000]; | |
| 63 float optical_flow_feature_error[1000]; | |
| 64 | |
| 65 CvSize optical_flow_window = cvSize(3,3); | |
| 66 | |
| 67 CvTermCriteria optical_flow_termination_criteria = cvTermCriteria( CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 20, .3 ); | |
| 68 IplImage* pyramid1 = ::allocateImage(frameSize, IPL_DEPTH_8U, 1); | |
| 69 IplImage* pyramid2 = ::allocateImage(frameSize, IPL_DEPTH_8U, 1); | |
| 70 | |
| 71 int pressedKey = '?'; | |
| 72 while (frame && !::interruptionKey(pressedKey)) { | |
| 73 cvGoodFeaturesToTrack(frame1_1C, eig_image, temp_image, frame1_features, &nFeatures, .01, .01, NULL); | |
| 74 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 ); | |
| 75 | |
| 76 for(int i = 0; i < nFeatures; i++) { | |
| 77 /* If Pyramidal Lucas Kanade didn't really find the feature, skip it. */ | |
| 78 if ( optical_flow_found_feature[i] == 0 ) continue; | |
| 79 | |
| 80 int line_thickness; line_thickness = 1; | |
| 81 /* CV_RGB(red, green, blue) is the red, green, and blue components | |
| 82 * of the color you want, each out of 255. | |
| 83 */ | |
| 84 CvScalar line_color; line_color = CV_RGB(255,0,0); | |
| 85 | |
| 86 /* Let's make the flow field look nice with arrows. */ | |
| 87 | |
| 88 /* The arrows will be a bit too short for a nice visualization because of the high framerate | |
| 89 * (ie: there's not much motion between the frames). So let's lengthen them by a factor of 3. | |
| 90 */ | |
| 91 CvPoint p,q; | |
| 92 p.x = (int) frame1_features[i].x; | |
| 93 p.y = (int) frame1_features[i].y; | |
| 94 q.x = (int) frame2_features[i].x; | |
| 95 q.y = (int) frame2_features[i].y; | |
| 96 | |
| 97 double angle; angle = atan2( (double) p.y - q.y, (double) p.x - q.x ); | |
| 98 double hypotenuse; hypotenuse = sqrt( square(p.y - q.y) + square(p.x - q.x) ); | |
| 99 | |
| 100 /* Here we lengthen the arrow by a factor of three. */ | |
| 101 q.x = (int) (p.x - 3 * hypotenuse * cos(angle)); | |
| 102 q.y = (int) (p.y - 3 * hypotenuse * sin(angle)); | |
| 103 | |
| 104 /* Now we draw the main line of the arrow. */ | |
| 105 /* "frame1" is the frame to draw on. | |
| 106 * "p" is the point where the line begins. | |
| 107 * "q" is the point where the line stops. | |
| 108 * "CV_AA" means antialiased drawing. | |
| 109 * "0" means no fractional bits in the center cooridinate or radius. | |
| 110 */ | |
| 111 cvLine( frame1, p, q, line_color, line_thickness, CV_AA, 0 ); | |
| 112 /* Now draw the tips of the arrow. I do some scaling so that the | |
| 113 * tips look proportional to the main line of the arrow. | |
| 114 */ | |
| 115 p.x = (int) (q.x + 9 * cos(angle + pi / 4)); | |
| 116 p.y = (int) (q.y + 9 * sin(angle + pi / 4)); | |
| 117 cvLine( frame1, p, q, line_color, line_thickness, CV_AA, 0 ); | |
| 118 p.x = (int) (q.x + 9 * cos(angle - pi / 4)); | |
| 119 p.y = (int) (q.y + 9 * sin(angle - pi / 4)); | |
| 120 cvLine( frame1, p, q, line_color, line_thickness, CV_AA, 0 ); | |
| 121 } | |
| 122 cvShowImage("Optical Flow", frame1); | |
| 123 //cvWaitKey(5); | |
| 124 pressedKey = cvWaitKey(5); | |
| 125 frame = cvQueryFrame(inputVideo); | |
| 126 frameNum++; | |
| 127 cout << frameNum << endl; | |
| 128 | |
| 129 cvCopy(frame2_1C, frame1_1C); | |
| 130 cvCopy(pyramid2, pyramid1); | |
| 131 cvConvertImage(frame, frame2_1C); | |
| 132 cvConvertImage(frame, frame1); | |
| 30 } | 133 } |
| 31 | 134 |
| 32 return 1; | 135 return 1; |
| 33 } | 136 } |
