• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <iostream>
2 #include <vector>
3 #include <sstream>
4 
5 #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"
11 
12 using namespace std;
13 using namespace cv;
14 using namespace cv::cuda;
15 
16 template <typename T>
mapVal(T x,T a,T b,T c,T d)17 inline T mapVal(T x, T a, T b, T c, T d)
18 {
19     x = ::max(::min(x, b), a);
20     return c + (d-c) * (x-a) / (b-a);
21 }
22 
colorizeFlow(const Mat & u,const Mat & v,Mat & dst)23 static void colorizeFlow(const Mat &u, const Mat &v, Mat &dst)
24 {
25     double uMin, uMax;
26     cv::minMaxLoc(u, &uMin, &uMax, 0, 0);
27     double vMin, vMax;
28     cv::minMaxLoc(v, &vMin, &vMax, 0, 0);
29     uMin = ::abs(uMin); uMax = ::abs(uMax);
30     vMin = ::abs(vMin); vMax = ::abs(vMax);
31     float dMax = static_cast<float>(::max(::max(uMin, uMax), ::max(vMin, vMax)));
32 
33     dst.create(u.size(), CV_8UC3);
34     for (int y = 0; y < u.rows; ++y)
35     {
36         for (int x = 0; x < u.cols; ++x)
37         {
38             dst.at<uchar>(y,3*x) = 0;
39             dst.at<uchar>(y,3*x+1) = (uchar)mapVal(-v.at<float>(y,x), -dMax, dMax, 0.f, 255.f);
40             dst.at<uchar>(y,3*x+2) = (uchar)mapVal(u.at<float>(y,x), -dMax, dMax, 0.f, 255.f);
41         }
42     }
43 }
44 
main(int argc,char ** argv)45 int main(int argc, char **argv)
46 {
47     CommandLineParser 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 }");
51 
52     cmd.about("Farneback's optical flow sample.");
53     if (cmd.has("help") || !cmd.check())
54     {
55         cmd.printMessage();
56         cmd.printErrors();
57         return 0;
58     }
59 
60 
61     string pathL = cmd.get<string>("left");
62     string pathR = cmd.get<string>("right");
63     if (pathL.empty()) cout << "Specify left image path\n";
64     if (pathR.empty()) cout << "Specify right image path\n";
65     if (pathL.empty() || pathR.empty()) return -1;
66 
67     Mat frameL = imread(pathL, IMREAD_GRAYSCALE);
68     Mat frameR = imread(pathR, IMREAD_GRAYSCALE);
69     if (frameL.empty()) cout << "Can't open '" << pathL << "'\n";
70     if (frameR.empty()) cout << "Can't open '" << pathR << "'\n";
71     if (frameL.empty() || frameR.empty()) return -1;
72 
73     GpuMat d_frameL(frameL), d_frameR(frameR);
74     GpuMat d_flow;
75     Ptr<cuda::FarnebackOpticalFlow> d_calc = cuda::FarnebackOpticalFlow::create();
76     Mat flowxy, flowx, flowy, image;
77 
78     bool running = true, gpuMode = true;
79     int64 t, t0=0, t1=1, tc0, tc1;
80 
81     cout << "Use 'm' for CPU/GPU toggling\n";
82 
83     while (running)
84     {
85         t = getTickCount();
86 
87         if (gpuMode)
88         {
89             tc0 = getTickCount();
90             d_calc->calc(d_frameL, d_frameR, d_flow);
91             tc1 = getTickCount();
92 
93             GpuMat planes[2];
94             cuda::split(d_flow, planes);
95 
96             planes[0].download(flowx);
97             planes[1].download(flowy);
98         }
99         else
100         {
101             tc0 = getTickCount();
102             calcOpticalFlowFarneback(
103                         frameL, frameR, flowxy, d_calc->getPyrScale(), d_calc->getNumLevels(), d_calc->getWinSize(),
104                         d_calc->getNumIters(), d_calc->getPolyN(), d_calc->getPolySigma(), d_calc->getFlags());
105             tc1 = getTickCount();
106 
107             Mat planes[] = {flowx, flowy};
108             split(flowxy, planes);
109             flowx = planes[0]; flowy = planes[1];
110         }
111 
112         colorizeFlow(flowx, flowy, image);
113 
114         stringstream s;
115         s << "mode: " << (gpuMode?"GPU":"CPU");
116         putText(image, s.str(), Point(5, 25), FONT_HERSHEY_SIMPLEX, 1., Scalar(255,0,255), 2);
117 
118         s.str("");
119         s << "opt. flow FPS: " << cvRound((getTickFrequency()/(tc1-tc0)));
120         putText(image, s.str(), Point(5, 65), FONT_HERSHEY_SIMPLEX, 1., Scalar(255,0,255), 2);
121 
122         s.str("");
123         s << "total FPS: " << cvRound((getTickFrequency()/(t1-t0)));
124         putText(image, s.str(), Point(5, 105), FONT_HERSHEY_SIMPLEX, 1., Scalar(255,0,255), 2);
125 
126         imshow("flow", image);
127 
128         char ch = (char)waitKey(3);
129         if (ch == 27)
130             running = false;
131         else if (ch == 'm' || ch == 'M')
132             gpuMode = !gpuMode;
133 
134         t0 = t;
135         t1 = getTickCount();
136     }
137 
138     return 0;
139 }
140