farneback_optical_flow.cpp 4.1 KB

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