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
9 #include "opencv2/core/ocl.hpp"
10 #include "opencv2/core/utility.hpp"
11 #include "opencv2/imgcodecs.hpp"
12 #include "opencv2/videoio.hpp"
13 #include "opencv2/highgui.hpp"
14 #include "opencv2/video.hpp"
19 static Mat getVisibleFlow(InputArray flow)
21 vector<UMat> flow_vec;
22 split(flow, flow_vec);
23 UMat magnitude, angle;
24 cartToPolar(flow_vec[0], flow_vec[1], magnitude, angle, true);
25 magnitude.convertTo(magnitude, CV_32F, 0.2);
27 hsv_vec.push_back(angle);
28 hsv_vec.push_back(UMat::ones(angle.size(), angle.type()));
29 hsv_vec.push_back(magnitude);
33 cvtColor(hsv, img, COLOR_HSV2BGR);
37 static Size fitSize(const Size & sz, const Size & bounds)
39 CV_Assert(!sz.empty());
40 if (sz.width > bounds.width || sz.height > bounds.height)
42 double scale = std::min((double)bounds.width / sz.width, (double)bounds.height / sz.height);
43 return Size(cvRound(sz.width * scale), cvRound(sz.height * scale));
48 int main(int argc, const char* argv[])
51 "{ h help | | print help message }"
52 "{ c camera | 0 | capture video from camera (device index starting from 0) }"
53 "{ a algorithm | fb | algorithm (supported: 'fb', 'dis')}"
54 "{ m cpu | | run without OpenCL }"
55 "{ v video | | use video as input }"
56 "{ o original | | use original frame size (do not resize to 640x480)}"
58 CommandLineParser parser(argc, argv, keys);
59 parser.about("This sample demonstrates using of dense optical flow algorithms.");
60 if (parser.has("help"))
62 parser.printMessage();
65 int camera = parser.get<int>("camera");
66 string algorithm = parser.get<string>("algorithm");
67 bool useCPU = parser.has("cpu");
68 string filename = parser.get<string>("video");
69 bool useOriginalSize = parser.has("original");
83 cout << "Can not open video stream: '" << (filename.empty() ? "<camera>" : filename) << "'" << endl;
87 Ptr<DenseOpticalFlow> alg;
88 if (algorithm == "fb")
89 alg = FarnebackOpticalFlow::create();
90 else if (algorithm == "dis")
91 alg = DISOpticalFlow::create(DISOpticalFlow::PRESET_FAST);
94 cout << "Invalid algorithm: " << algorithm << endl;
98 ocl::setUseOpenCL(!useCPU);
100 cout << "Press 'm' to toggle CPU/GPU processing mode" << endl;
101 cout << "Press ESC or 'q' to exit" << endl;
103 UMat prevFrame, frame, input_frame, flow;
106 if (!cap.read(input_frame) || input_frame.empty())
108 cout << "Finished reading: empty frame" << endl;
111 Size small_size = fitSize(input_frame.size(), Size(640, 480));
112 if (!useOriginalSize && small_size != input_frame.size())
113 resize(input_frame, frame, small_size);
116 cvtColor(frame, frame, COLOR_BGR2GRAY);
117 imshow("frame", frame);
118 if (!prevFrame.empty())
120 int64 t = getTickCount();
121 alg->calc(prevFrame, frame, flow);
122 t = getTickCount() - t;
124 Mat img = getVisibleFlow(flow);
126 buf << "Algo: " << algorithm << " | "
127 << "Mode: " << (useCPU ? "CPU" : "GPU") << " | "
128 << "FPS: " << fixed << setprecision(1) << (getTickFrequency() / (double)t);
129 putText(img, buf.str(), Point(10, 30), FONT_HERSHEY_PLAIN, 2.0, Scalar(0, 0, 255), 2, LINE_AA);
130 imshow("Dense optical flow field", img);
133 frame.copyTo(prevFrame);
135 // interact with user
136 const char key = (char)waitKey(30);
137 if (key == 27 || key == 'q') // ESC
139 cout << "Exit requested" << endl;
145 ocl::setUseOpenCL(!useCPU);
146 cout << "Set processing mode to: " << (useCPU ? "CPU" : "GPU") << endl;