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