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