comparison c/optical-flow.cpp @ 15:3ead4bcd001c

cleaned optical flow
author Nicolas Saunier <nico@confins.net>
date Sun, 15 Nov 2009 01:04:10 -0500
parents ff5403319cec
children bc4ea09b1743
comparison
equal deleted inserted replaced
14:e7bbe8465591 15:3ead4bcd001c
68 IplImage* pyramid1 = ::allocateImage(frameSize, IPL_DEPTH_8U, 1); 68 IplImage* pyramid1 = ::allocateImage(frameSize, IPL_DEPTH_8U, 1);
69 IplImage* pyramid2 = ::allocateImage(frameSize, IPL_DEPTH_8U, 1); 69 IplImage* pyramid2 = ::allocateImage(frameSize, IPL_DEPTH_8U, 1);
70 70
71 int pressedKey = '?'; 71 int pressedKey = '?';
72 while (frame && !::interruptionKey(pressedKey)) { 72 while (frame && !::interruptionKey(pressedKey)) {
73 cvGoodFeaturesToTrack(frame1_1C, eig_image, temp_image, frame1_features, &nFeatures, .01, .01, NULL); 73 cvGoodFeaturesToTrack(frame1_1C, eig_image, temp_image, frame1_features, &nFeatures, 0.05 /*quality*/, 1/* min dist*/, 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 ); 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 75
76 for(int i = 0; i < nFeatures; i++) { 76 for(int i = 0; i < nFeatures; i++) {
77 /* If Pyramidal Lucas Kanade didn't really find the feature, skip it. */ 77 if (optical_flow_found_feature[i] != 0) {
78 if ( optical_flow_found_feature[i] == 0 ) continue; 78 int line_thickness = 1;
79 CvScalar line_color = CV_RGB(255,0,0);
79 80
80 int line_thickness; line_thickness = 1; 81 CvPoint p,q;
81 /* CV_RGB(red, green, blue) is the red, green, and blue components 82 p.x = lrintf(frame1_features[i].x);
82 * of the color you want, each out of 255. 83 p.y = lrintf(frame1_features[i].y);
83 */ 84 q.x = lrintf(frame2_features[i].x);
84 CvScalar line_color; line_color = CV_RGB(255,0,0); 85 q.y = lrintf(frame2_features[i].y);
86
87 double dx = frame2_features[i].x-frame1_features[i].x;
88 double dy = frame2_features[i].y-frame1_features[i].y;
89
90 double angle = atan2( (double) p.y - q.y, (double) p.x - q.x );
91 double dist = sqrt(square(dx) + square(dy));
92
93 if (dist > 2.) { // min motion distance
94 q.x = lrintf(frame1_features[i].x+dx*3); //(p.x - 3 * hypotenuse * cos(angle));
95 q.y = lrintf(frame1_features[i].y+dy*3); //(p.y - 3 * hypotenuse * sin(angle));
85 96
86 /* Let's make the flow field look nice with arrows. */ 97 /* Now we draw the main line of the arrow. */
87 98 cvLine( frame1, p, q, line_color, line_thickness, CV_AA, 0 );
88 /* The arrows will be a bit too short for a nice visualization because of the high framerate 99 /* Now draw the tips of the arrow. I do some scaling so that the
89 * (ie: there's not much motion between the frames). So let's lengthen them by a factor of 3. 100 * tips look proportional to the main line of the arrow.
90 */ 101 */
91 CvPoint p,q; 102 float arrowSize = 6;
92 p.x = (int) frame1_features[i].x; 103 p.x = lrintf(q.x + arrowSize * cos(angle + pi / 4));
93 p.y = (int) frame1_features[i].y; 104 p.y = lrintf(q.y + arrowSize * sin(angle + pi / 4));
94 q.x = (int) frame2_features[i].x; 105 cvLine( frame1, p, q, line_color, line_thickness, CV_AA, 0 );
95 q.y = (int) frame2_features[i].y; 106 p.x = lrintf(q.x + arrowSize * cos(angle - pi / 4));
96 107 p.y = lrintf(q.y + arrowSize * sin(angle - pi / 4));
97 double angle; angle = atan2( (double) p.y - q.y, (double) p.x - q.x ); 108 cvLine( frame1, p, q, line_color, line_thickness, CV_AA, 0 );
98 double hypotenuse; hypotenuse = sqrt( square(p.y - q.y) + square(p.x - q.x) ); 109 }
99 110 }
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 } 111 }
122 cvShowImage("Optical Flow", frame1); 112 cvShowImage("Optical Flow", frame1);
123 //cvWaitKey(5);
124 pressedKey = cvWaitKey(5); 113 pressedKey = cvWaitKey(5);
125 frame = cvQueryFrame(inputVideo); 114 frame = cvQueryFrame(inputVideo);
126 frameNum++; 115 frameNum++;
127 cout << frameNum << endl; 116 cout << frameNum << endl;
128 117