opencv/samples/gpu/farneback_optical_flow.cpp

135 lines
3.9 KiB
C++
Raw Normal View History

2012-02-20 16:31:10 +08:00
#include <iostream>
#include <vector>
#include <sstream>
#include "opencv2/core.hpp"
#include "opencv2/core/utility.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/video.hpp"
2013-07-23 17:19:54 +08:00
#include "opencv2/gpuoptflow.hpp"
2012-02-20 16:31:10 +08:00
using namespace std;
using namespace cv;
2013-08-28 19:45:13 +08:00
using namespace cv::cuda;
2012-02-20 16:31:10 +08:00
template <typename T>
inline T mapVal(T x, T a, T b, T c, T d)
{
x = ::max(::min(x, b), a);
return c + (d-c) * (x-a) / (b-a);
}
2012-06-08 01:21:29 +08:00
static void colorizeFlow(const Mat &u, const Mat &v, Mat &dst)
2012-02-20 16:31:10 +08:00
{
double uMin, uMax;
cv::minMaxLoc(u, &uMin, &uMax, 0, 0);
2012-02-20 16:31:10 +08:00
double vMin, vMax;
cv::minMaxLoc(v, &vMin, &vMax, 0, 0);
2012-02-20 16:31:10 +08:00
uMin = ::abs(uMin); uMax = ::abs(uMax);
vMin = ::abs(vMin); vMax = ::abs(vMax);
float dMax = static_cast<float>(::max(::max(uMin, uMax), ::max(vMin, vMax)));
2012-02-20 16:31:10 +08:00
dst.create(u.size(), CV_8UC3);
for (int y = 0; y < u.rows; ++y)
{
for (int x = 0; x < u.cols; ++x)
{
dst.at<uchar>(y,3*x) = 0;
dst.at<uchar>(y,3*x+1) = (uchar)mapVal(-v.at<float>(y,x), -dMax, dMax, 0.f, 255.f);
dst.at<uchar>(y,3*x+2) = (uchar)mapVal(u.at<float>(y,x), -dMax, dMax, 0.f, 255.f);
}
}
}
int main(int argc, char **argv)
{
CommandLineParser cmd(argc, argv,
"{ l left | | specify left image }"
"{ r right | | specify right image }"
"{ h help | | print help message }");
2012-02-20 16:31:10 +08:00
cmd.about("Farneback's optical flow sample.");
if (cmd.has("help") || !cmd.check())
2012-02-20 16:31:10 +08:00
{
cmd.printMessage();
cmd.printErrors();
2012-02-20 16:31:10 +08:00
return 0;
}
2012-02-20 16:31:10 +08:00
string pathL = cmd.get<string>("left");
string pathR = cmd.get<string>("right");
if (pathL.empty()) cout << "Specify left image path\n";
if (pathR.empty()) cout << "Specify right image path\n";
if (pathL.empty() || pathR.empty()) return -1;
Mat frameL = imread(pathL, IMREAD_GRAYSCALE);
Mat frameR = imread(pathR, IMREAD_GRAYSCALE);
if (frameL.empty()) cout << "Can't open '" << pathL << "'\n";
if (frameR.empty()) cout << "Can't open '" << pathR << "'\n";
if (frameL.empty() || frameR.empty()) return -1;
GpuMat d_frameL(frameL), d_frameR(frameR);
GpuMat d_flowx, d_flowy;
FarnebackOpticalFlow d_calc;
Mat flowxy, flowx, flowy, image;
bool running = true, gpuMode = true;
int64 t, t0=0, t1=1, tc0, tc1;
cout << "Use 'm' for CPU/GPU toggling\n";
while (running)
{
t = getTickCount();
if (gpuMode)
{
tc0 = getTickCount();
d_calc(d_frameL, d_frameR, d_flowx, d_flowy);
tc1 = getTickCount();
d_flowx.download(flowx);
d_flowy.download(flowy);
}
else
{
tc0 = getTickCount();
calcOpticalFlowFarneback(
frameL, frameR, flowxy, d_calc.pyrScale, d_calc.numLevels, d_calc.winSize,
d_calc.numIters, d_calc.polyN, d_calc.polySigma, d_calc.flags);
tc1 = getTickCount();
Mat planes[] = {flowx, flowy};
split(flowxy, planes);
flowx = planes[0]; flowy = planes[1];
}
colorizeFlow(flowx, flowy, image);
stringstream s;
s << "mode: " << (gpuMode?"GPU":"CPU");
putText(image, s.str(), Point(5, 25), FONT_HERSHEY_SIMPLEX, 1., Scalar(255,0,255), 2);
s.str("");
s << "opt. flow FPS: " << cvRound((getTickFrequency()/(tc1-tc0)));
putText(image, s.str(), Point(5, 65), FONT_HERSHEY_SIMPLEX, 1., Scalar(255,0,255), 2);
2012-02-20 16:31:10 +08:00
s.str("");
s << "total FPS: " << cvRound((getTickFrequency()/(t1-t0)));
putText(image, s.str(), Point(5, 105), FONT_HERSHEY_SIMPLEX, 1., Scalar(255,0,255), 2);
2012-02-20 16:31:10 +08:00
imshow("flow", image);
char ch = (char)waitKey(3);
if (ch == 27)
running = false;
else if (ch == 'm' || ch == 'M')
gpuMode = !gpuMode;
t0 = t;
t1 = getTickCount();
}
return 0;
}