Mercurial Hosting > traffic-intelligence
view c/optical-flow.cpp @ 917:89cc05867c4c
reorg and work in progress
author | Nicolas Saunier <nicolas.saunier@polymtl.ca> |
---|---|
date | Tue, 04 Jul 2017 18:00:01 -0400 |
parents | bc4ea09b1743 |
children |
line wrap: on
line source
#include "cvutils.hpp" #include "utils.hpp" #include "opencv/cv.h" #include "opencv/highgui.h" #include <iostream> #include <ctime> /* MSVC does not have lrintf */ #ifdef _MSC_VER static inline long lrintf(float f){ /* x64 does not supported embedded assembly */ #ifdef _M_X64 return (long)((f>0.0f) ? (f + 0.5f):(f -0.5f)); #else int i; _asm{ fld f fistp i }; return i; #endif } #endif 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, 0.05 /*quality*/, 1/* min dist*/, 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 (optical_flow_found_feature[i] != 0) { int line_thickness = 1; CvScalar line_color = CV_RGB(255,0,0); CvPoint p,q; p.x = lrintf(frame1_features[i].x); p.y = lrintf(frame1_features[i].y); q.x = lrintf(frame2_features[i].x); q.y = lrintf(frame2_features[i].y); double dx = frame2_features[i].x-frame1_features[i].x; double dy = frame2_features[i].y-frame1_features[i].y; double angle = atan2( (double) p.y - q.y, (double) p.x - q.x ); double dist = sqrt(square(dx) + square(dy)); if (dist > 2.) { // min motion distance q.x = lrintf(frame1_features[i].x+dx*3); //(p.x - 3 * hypotenuse * cos(angle)); q.y = lrintf(frame1_features[i].y+dy*3); //(p.y - 3 * hypotenuse * sin(angle)); /* Now we draw the main line of the arrow. */ 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. */ float arrowSize = 6; p.x = lrintf(q.x + arrowSize * cos(angle + pi / 4)); p.y = lrintf(q.y + arrowSize * sin(angle + pi / 4)); cvLine( frame1, p, q, line_color, line_thickness, CV_AA, 0 ); p.x = lrintf(q.x + arrowSize * cos(angle - pi / 4)); p.y = lrintf(q.y + arrowSize * sin(angle - pi / 4)); cvLine( frame1, p, q, line_color, line_thickness, CV_AA, 0 ); } } } cvShowImage("Optical Flow", frame1); 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; }