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 }