dense_optical_flow.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. // This file is part of OpenCV project.
  2. // It is subject to the license terms in the LICENSE file found in the top-level directory
  3. // of this distribution and at http://opencv.org/license.html
  4. #include <iostream>
  5. #include <iomanip>
  6. #include <vector>
  7. #include "opencv2/core/ocl.hpp"
  8. #include "opencv2/core/utility.hpp"
  9. #include "opencv2/imgcodecs.hpp"
  10. #include "opencv2/videoio.hpp"
  11. #include "opencv2/highgui.hpp"
  12. #include "opencv2/video.hpp"
  13. using namespace std;
  14. using namespace cv;
  15. static Mat getVisibleFlow(InputArray flow)
  16. {
  17. vector<UMat> flow_vec;
  18. split(flow, flow_vec);
  19. UMat magnitude, angle;
  20. cartToPolar(flow_vec[0], flow_vec[1], magnitude, angle, true);
  21. magnitude.convertTo(magnitude, CV_32F, 0.2);
  22. vector<UMat> hsv_vec;
  23. hsv_vec.push_back(angle);
  24. hsv_vec.push_back(UMat::ones(angle.size(), angle.type()));
  25. hsv_vec.push_back(magnitude);
  26. UMat hsv;
  27. merge(hsv_vec, hsv);
  28. Mat img;
  29. cvtColor(hsv, img, COLOR_HSV2BGR);
  30. return img;
  31. }
  32. static Size fitSize(const Size & sz, const Size & bounds)
  33. {
  34. CV_Assert(!sz.empty());
  35. if (sz.width > bounds.width || sz.height > bounds.height)
  36. {
  37. double scale = std::min((double)bounds.width / sz.width, (double)bounds.height / sz.height);
  38. return Size(cvRound(sz.width * scale), cvRound(sz.height * scale));
  39. }
  40. return sz;
  41. }
  42. int main(int argc, const char* argv[])
  43. {
  44. const char* keys =
  45. "{ h help | | print help message }"
  46. "{ c camera | 0 | capture video from camera (device index starting from 0) }"
  47. "{ a algorithm | fb | algorithm (supported: 'fb', 'dis')}"
  48. "{ m cpu | | run without OpenCL }"
  49. "{ v video | | use video as input }"
  50. "{ o original | | use original frame size (do not resize to 640x480)}"
  51. ;
  52. CommandLineParser parser(argc, argv, keys);
  53. parser.about("This sample demonstrates using of dense optical flow algorithms.");
  54. if (parser.has("help"))
  55. {
  56. parser.printMessage();
  57. return 0;
  58. }
  59. int camera = parser.get<int>("camera");
  60. string algorithm = parser.get<string>("algorithm");
  61. bool useCPU = parser.has("cpu");
  62. string filename = parser.get<string>("video");
  63. bool useOriginalSize = parser.has("original");
  64. if (!parser.check())
  65. {
  66. parser.printErrors();
  67. return 1;
  68. }
  69. VideoCapture cap;
  70. if(filename.empty())
  71. cap.open(camera);
  72. else
  73. cap.open(filename);
  74. if (!cap.isOpened())
  75. {
  76. cout << "Can not open video stream: '" << (filename.empty() ? "<camera>" : filename) << "'" << endl;
  77. return 2;
  78. }
  79. Ptr<DenseOpticalFlow> alg;
  80. if (algorithm == "fb")
  81. alg = FarnebackOpticalFlow::create();
  82. else if (algorithm == "dis")
  83. alg = DISOpticalFlow::create(DISOpticalFlow::PRESET_FAST);
  84. else
  85. {
  86. cout << "Invalid algorithm: " << algorithm << endl;
  87. return 3;
  88. }
  89. ocl::setUseOpenCL(!useCPU);
  90. cout << "Press 'm' to toggle CPU/GPU processing mode" << endl;
  91. cout << "Press ESC or 'q' to exit" << endl;
  92. UMat prevFrame, frame, input_frame, flow;
  93. for(;;)
  94. {
  95. if (!cap.read(input_frame) || input_frame.empty())
  96. {
  97. cout << "Finished reading: empty frame" << endl;
  98. break;
  99. }
  100. Size small_size = fitSize(input_frame.size(), Size(640, 480));
  101. if (!useOriginalSize && small_size != input_frame.size())
  102. resize(input_frame, frame, small_size);
  103. else
  104. frame = input_frame;
  105. cvtColor(frame, frame, COLOR_BGR2GRAY);
  106. imshow("frame", frame);
  107. if (!prevFrame.empty())
  108. {
  109. int64 t = getTickCount();
  110. alg->calc(prevFrame, frame, flow);
  111. t = getTickCount() - t;
  112. {
  113. Mat img = getVisibleFlow(flow);
  114. ostringstream buf;
  115. buf << "Algo: " << algorithm << " | "
  116. << "Mode: " << (useCPU ? "CPU" : "GPU") << " | "
  117. << "FPS: " << fixed << setprecision(1) << (getTickFrequency() / (double)t);
  118. putText(img, buf.str(), Point(10, 30), FONT_HERSHEY_PLAIN, 2.0, Scalar(0, 0, 255), 2, LINE_AA);
  119. imshow("Dense optical flow field", img);
  120. }
  121. }
  122. frame.copyTo(prevFrame);
  123. // interact with user
  124. const char key = (char)waitKey(30);
  125. if (key == 27 || key == 'q') // ESC
  126. {
  127. cout << "Exit requested" << endl;
  128. break;
  129. }
  130. else if (key == 'm')
  131. {
  132. useCPU = !useCPU;
  133. ocl::setUseOpenCL(!useCPU);
  134. cout << "Set processing mode to: " << (useCPU ? "CPU" : "GPU") << endl;
  135. }
  136. }
  137. return 0;
  138. }