Path: blob/master/samples/gpu/farneback_optical_flow.cpp
16337 views
#include <iostream>1#include <vector>2#include <sstream>3#include <cmath>45#include "opencv2/core.hpp"6#include "opencv2/core/utility.hpp"7#include "opencv2/highgui.hpp"8#include "opencv2/video.hpp"9#include "opencv2/cudaoptflow.hpp"10#include "opencv2/cudaarithm.hpp"1112using namespace std;13using namespace cv;14using namespace cv::cuda;1516template <typename T>17inline T mapVal(T x, T a, T b, T c, T d)18{19x = ::max(::min(x, b), a);20return c + (d-c) * (x-a) / (b-a);21}2223static void colorizeFlow(const Mat &u, const Mat &v, Mat &dst)24{25double uMin, uMax;26cv::minMaxLoc(u, &uMin, &uMax, 0, 0);27double vMin, vMax;28cv::minMaxLoc(v, &vMin, &vMax, 0, 0);29uMin = ::abs(uMin); uMax = ::abs(uMax);30vMin = ::abs(vMin); vMax = ::abs(vMax);31float dMax = static_cast<float>(::max(::max(uMin, uMax), ::max(vMin, vMax)));3233dst.create(u.size(), CV_8UC3);34for (int y = 0; y < u.rows; ++y)35{36for (int x = 0; x < u.cols; ++x)37{38dst.at<uchar>(y,3*x) = 0;39dst.at<uchar>(y,3*x+1) = (uchar)mapVal(-v.at<float>(y,x), -dMax, dMax, 0.f, 255.f);40dst.at<uchar>(y,3*x+2) = (uchar)mapVal(u.at<float>(y,x), -dMax, dMax, 0.f, 255.f);41}42}43}4445int main(int argc, char **argv)46{47CommandLineParser cmd(argc, argv,48"{ l left | ../data/basketball1.png | specify left image }"49"{ r right | ../data/basketball2.png | specify right image }"50"{ h help | | print help message }");5152cmd.about("Farneback's optical flow sample.");53if (cmd.has("help") || !cmd.check())54{55cmd.printMessage();56cmd.printErrors();57return 0;58}596061string pathL = cmd.get<string>("left");62string pathR = cmd.get<string>("right");63if (pathL.empty()) cout << "Specify left image path\n";64if (pathR.empty()) cout << "Specify right image path\n";65if (pathL.empty() || pathR.empty()) return -1;6667Mat frameL = imread(pathL, IMREAD_GRAYSCALE);68Mat frameR = imread(pathR, IMREAD_GRAYSCALE);69if (frameL.empty()) cout << "Can't open '" << pathL << "'\n";70if (frameR.empty()) cout << "Can't open '" << pathR << "'\n";71if (frameL.empty() || frameR.empty()) return -1;7273GpuMat d_frameL(frameL), d_frameR(frameR);74GpuMat d_flow;75Ptr<cuda::FarnebackOpticalFlow> d_calc = cuda::FarnebackOpticalFlow::create();76Mat flowxy, flowx, flowy, image;7778bool running = true, gpuMode = true;79int64 t, t0=0, t1=1, tc0, tc1;8081cout << "Use 'm' for CPU/GPU toggling\n";8283while (running)84{85t = getTickCount();8687if (gpuMode)88{89tc0 = getTickCount();90d_calc->calc(d_frameL, d_frameR, d_flow);91tc1 = getTickCount();9293GpuMat planes[2];94cuda::split(d_flow, planes);9596planes[0].download(flowx);97planes[1].download(flowy);98}99else100{101tc0 = getTickCount();102calcOpticalFlowFarneback(103frameL, frameR, flowxy, d_calc->getPyrScale(), d_calc->getNumLevels(), d_calc->getWinSize(),104d_calc->getNumIters(), d_calc->getPolyN(), d_calc->getPolySigma(), d_calc->getFlags());105tc1 = getTickCount();106107Mat planes[] = {flowx, flowy};108split(flowxy, planes);109flowx = planes[0]; flowy = planes[1];110}111112colorizeFlow(flowx, flowy, image);113114stringstream s;115s << "mode: " << (gpuMode?"GPU":"CPU");116putText(image, s.str(), Point(5, 25), FONT_HERSHEY_SIMPLEX, 1., Scalar(255,0,255), 2);117118s.str("");119s << "opt. flow FPS: " << cvRound((getTickFrequency()/(tc1-tc0)));120putText(image, s.str(), Point(5, 65), FONT_HERSHEY_SIMPLEX, 1., Scalar(255,0,255), 2);121122s.str("");123s << "total FPS: " << cvRound((getTickFrequency()/(t1-t0)));124putText(image, s.str(), Point(5, 105), FONT_HERSHEY_SIMPLEX, 1., Scalar(255,0,255), 2);125126imshow("flow", image);127128char ch = (char)waitKey(3);129if (ch == 27)130running = false;131else if (ch == 'm' || ch == 'M')132gpuMode = !gpuMode;133134t0 = t;135t1 = getTickCount();136}137138return 0;139}140141142