Path: blob/master/modules/superres/src/optical_flow.cpp
16354 views
/*M///////////////////////////////////////////////////////////////////////////////////////1//2// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.3//4// By downloading, copying, installing or using the software you agree to this license.5// If you do not agree to this license, do not download, install,6// copy or use the software.7//8//9// License Agreement10// For Open Source Computer Vision Library11//12// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.13// Copyright (C) 2009, Willow Garage Inc., all rights reserved.14// Third party copyrights are property of their respective owners.15//16// Redistribution and use in source and binary forms, with or without modification,17// are permitted provided that the following conditions are met:18//19// * Redistribution's of source code must retain the above copyright notice,20// this list of conditions and the following disclaimer.21//22// * Redistribution's in binary form must reproduce the above copyright notice,23// this list of conditions and the following disclaimer in the documentation24// and/or other materials provided with the distribution.25//26// * The name of the copyright holders may not be used to endorse or promote products27// derived from this software without specific prior written permission.28//29// This software is provided by the copyright holders and contributors "as is" and30// any express or implied warranties, including, but not limited to, the implied31// warranties of merchantability and fitness for a particular purpose are disclaimed.32// In no event shall the Intel Corporation or contributors be liable for any direct,33// indirect, incidental, special, exemplary, or consequential damages34// (including, but not limited to, procurement of substitute goods or services;35// loss of use, data, or profits; or business interruption) however caused36// and on any theory of liability, whether in contract, strict liability,37// or tort (including negligence or otherwise) arising in any way out of38// the use of this software, even if advised of the possibility of such damage.39//40//M*/4142#include "precomp.hpp"43#include "opencv2/core/opencl/ocl_defs.hpp"4445using namespace cv;46using namespace cv::cuda;47using namespace cv::superres;48using namespace cv::superres::detail;4950///////////////////////////////////////////////////////////////////51// CpuOpticalFlow5253namespace54{55class CpuOpticalFlow : public virtual cv::superres::DenseOpticalFlowExt56{57public:58explicit CpuOpticalFlow(int work_type);5960void calc(InputArray frame0, InputArray frame1, OutputArray flow1, OutputArray flow2) CV_OVERRIDE;61void collectGarbage() CV_OVERRIDE;6263protected:64virtual void impl(InputArray input0, InputArray input1, OutputArray dst) = 0;6566private:67#ifdef HAVE_OPENCL68bool ocl_calc(InputArray frame0, InputArray frame1, OutputArray flow1, OutputArray flow2);69#endif7071int work_type_;7273// Mat74Mat buf_[6];75Mat flow_;76Mat flows_[2];7778// UMat79UMat ubuf_[6];80UMat uflow_;81std::vector<UMat> uflows_;82};8384CpuOpticalFlow::CpuOpticalFlow(int work_type) :85work_type_(work_type)86{87}8889#ifdef HAVE_OPENCL90bool CpuOpticalFlow::ocl_calc(InputArray _frame0, InputArray _frame1, OutputArray _flow1, OutputArray _flow2)91{92UMat frame0 = arrGetUMat(_frame0, ubuf_[0]);93UMat frame1 = arrGetUMat(_frame1, ubuf_[1]);9495CV_Assert( frame1.type() == frame0.type() );96CV_Assert( frame1.size() == frame0.size() );9798UMat input0 = convertToType(frame0, work_type_, ubuf_[2], ubuf_[3]);99UMat input1 = convertToType(frame1, work_type_, ubuf_[4], ubuf_[5]);100101if (!_flow2.needed())102{103impl(input0, input1, _flow1);104return true;105}106107impl(input0, input1, uflow_);108109if (!_flow2.needed())110arrCopy(uflow_, _flow1);111else112{113split(uflow_, uflows_);114115arrCopy(uflows_[0], _flow1);116arrCopy(uflows_[1], _flow2);117}118119return true;120}121#endif122123void CpuOpticalFlow::calc(InputArray _frame0, InputArray _frame1, OutputArray _flow1, OutputArray _flow2)124{125CV_INSTRUMENT_REGION();126127CV_OCL_RUN(_flow1.isUMat() && (_flow2.isUMat() || !_flow2.needed()),128ocl_calc(_frame0, _frame1, _flow1, _flow2))129130Mat frame0 = arrGetMat(_frame0, buf_[0]);131Mat frame1 = arrGetMat(_frame1, buf_[1]);132133CV_Assert( frame1.type() == frame0.type() );134CV_Assert( frame1.size() == frame0.size() );135136Mat input0 = convertToType(frame0, work_type_, buf_[2], buf_[3]);137Mat input1 = convertToType(frame1, work_type_, buf_[4], buf_[5]);138139if (!_flow2.needed() && _flow1.kind() < _InputArray::OPENGL_BUFFER)140{141impl(input0, input1, _flow1);142return;143}144145impl(input0, input1, flow_);146147if (!_flow2.needed())148arrCopy(flow_, _flow1);149else150{151split(flow_, flows_);152153arrCopy(flows_[0], _flow1);154arrCopy(flows_[1], _flow2);155}156}157158void CpuOpticalFlow::collectGarbage()159{160// Mat161for (int i = 0; i < 6; ++i)162buf_[i].release();163flow_.release();164flows_[0].release();165flows_[1].release();166167// UMat168for (int i = 0; i < 6; ++i)169ubuf_[i].release();170uflow_.release();171uflows_[0].release();172uflows_[1].release();173}174}175176///////////////////////////////////////////////////////////////////177// Farneback178179namespace180{181class Farneback CV_FINAL : public CpuOpticalFlow, public cv::superres::FarnebackOpticalFlow182{183public:184Farneback();185void calc(InputArray frame0, InputArray frame1, OutputArray flow1, OutputArray flow2) CV_OVERRIDE;186void collectGarbage() CV_OVERRIDE;187188inline double getPyrScale() const CV_OVERRIDE { return pyrScale_; }189inline void setPyrScale(double val) CV_OVERRIDE { pyrScale_ = val; }190inline int getLevelsNumber() const CV_OVERRIDE { return numLevels_; }191inline void setLevelsNumber(int val) CV_OVERRIDE { numLevels_ = val; }192inline int getWindowSize() const CV_OVERRIDE { return winSize_; }193inline void setWindowSize(int val) CV_OVERRIDE { winSize_ = val; }194inline int getIterations() const CV_OVERRIDE { return numIters_; }195inline void setIterations(int val) CV_OVERRIDE { numIters_ = val; }196inline int getPolyN() const CV_OVERRIDE { return polyN_; }197inline void setPolyN(int val) CV_OVERRIDE { polyN_ = val; }198inline double getPolySigma() const CV_OVERRIDE { return polySigma_; }199inline void setPolySigma(double val) CV_OVERRIDE { polySigma_ = val; }200inline int getFlags() const CV_OVERRIDE { return flags_; }201inline void setFlags(int val) CV_OVERRIDE { flags_ = val; }202203protected:204void impl(InputArray input0, InputArray input1, OutputArray dst) CV_OVERRIDE;205206private:207double pyrScale_;208int numLevels_;209int winSize_;210int numIters_;211int polyN_;212double polySigma_;213int flags_;214};215216Farneback::Farneback() : CpuOpticalFlow(CV_8UC1)217{218pyrScale_ = 0.5;219numLevels_ = 5;220winSize_ = 13;221numIters_ = 10;222polyN_ = 5;223polySigma_ = 1.1;224flags_ = 0;225}226227void Farneback::calc(InputArray frame0, InputArray frame1, OutputArray flow1, OutputArray flow2)228{229CV_INSTRUMENT_REGION();230231CpuOpticalFlow::calc(frame0, frame1, flow1, flow2);232}233234void Farneback::collectGarbage()235{236CpuOpticalFlow::collectGarbage();237}238239void Farneback::impl(InputArray input0, InputArray input1, OutputArray dst)240{241calcOpticalFlowFarneback(input0, input1, InputOutputArray(dst), pyrScale_,242numLevels_, winSize_, numIters_,243polyN_, polySigma_, flags_);244}245}246247Ptr<cv::superres::FarnebackOpticalFlow> cv::superres::createOptFlow_Farneback()248{249return makePtr<Farneback>();250}251252///////////////////////////////////////////////////////////////////253// Simple254255/*256namespace257{258class Simple : public CpuOpticalFlow259{260public:261AlgorithmInfo* info() const;262263Simple();264265protected:266void impl(InputArray input0, InputArray input1, OutputArray dst);267268private:269int layers_;270int averagingBlockSize_;271int maxFlow_;272double sigmaDist_;273double sigmaColor_;274int postProcessWindow_;275double sigmaDistFix_;276double sigmaColorFix_;277double occThr_;278int upscaleAveragingRadius_;279double upscaleSigmaDist_;280double upscaleSigmaColor_;281double speedUpThr_;282};283284CV_INIT_ALGORITHM(Simple, "DenseOpticalFlowExt.Simple",285obj.info()->addParam(obj, "layers", obj.layers_);286obj.info()->addParam(obj, "averagingBlockSize", obj.averagingBlockSize_);287obj.info()->addParam(obj, "maxFlow", obj.maxFlow_);288obj.info()->addParam(obj, "sigmaDist", obj.sigmaDist_);289obj.info()->addParam(obj, "sigmaColor", obj.sigmaColor_);290obj.info()->addParam(obj, "postProcessWindow", obj.postProcessWindow_);291obj.info()->addParam(obj, "sigmaDistFix", obj.sigmaDistFix_);292obj.info()->addParam(obj, "sigmaColorFix", obj.sigmaColorFix_);293obj.info()->addParam(obj, "occThr", obj.occThr_);294obj.info()->addParam(obj, "upscaleAveragingRadius", obj.upscaleAveragingRadius_);295obj.info()->addParam(obj, "upscaleSigmaDist", obj.upscaleSigmaDist_);296obj.info()->addParam(obj, "upscaleSigmaColor", obj.upscaleSigmaColor_);297obj.info()->addParam(obj, "speedUpThr", obj.speedUpThr_))298299Simple::Simple() : CpuOpticalFlow(CV_8UC3)300{301layers_ = 3;302averagingBlockSize_ = 2;303maxFlow_ = 4;304sigmaDist_ = 4.1;305sigmaColor_ = 25.5;306postProcessWindow_ = 18;307sigmaDistFix_ = 55.0;308sigmaColorFix_ = 25.5;309occThr_ = 0.35;310upscaleAveragingRadius_ = 18;311upscaleSigmaDist_ = 55.0;312upscaleSigmaColor_ = 25.5;313speedUpThr_ = 10;314}315316void Simple::impl(InputArray _input0, InputArray _input1, OutputArray _dst)317{318calcOpticalFlowSF(_input0, _input1, _dst,319layers_,320averagingBlockSize_,321maxFlow_,322sigmaDist_,323sigmaColor_,324postProcessWindow_,325sigmaDistFix_,326sigmaColorFix_,327occThr_,328upscaleAveragingRadius_,329upscaleSigmaDist_,330upscaleSigmaColor_,331speedUpThr_);332}333}334335Ptr<DenseOpticalFlowExt> cv::superres::createOptFlow_Simple()336{337return makePtr<Simple>();338}*/339340///////////////////////////////////////////////////////////////////341// DualTVL1342343namespace344{345class DualTVL1 CV_FINAL : public CpuOpticalFlow, public virtual cv::superres::DualTVL1OpticalFlow346{347public:348DualTVL1();349void calc(InputArray frame0, InputArray frame1, OutputArray flow1, OutputArray flow2) CV_OVERRIDE;350void collectGarbage() CV_OVERRIDE;351352inline double getTau() const CV_OVERRIDE { return (*alg_).getTau(); }353inline void setTau(double val) CV_OVERRIDE { (*alg_).setTau(val); }354inline double getLambda() const CV_OVERRIDE { return (*alg_).getLambda(); }355inline void setLambda(double val) CV_OVERRIDE { (*alg_).setLambda(val); }356inline double getTheta() const CV_OVERRIDE { return (*alg_).getTheta(); }357inline void setTheta(double val) CV_OVERRIDE { (*alg_).setTheta(val); }358inline int getScalesNumber() const CV_OVERRIDE { return (*alg_).getScalesNumber(); }359inline void setScalesNumber(int val) CV_OVERRIDE { (*alg_).setScalesNumber(val); }360inline int getWarpingsNumber() const CV_OVERRIDE { return (*alg_).getWarpingsNumber(); }361inline void setWarpingsNumber(int val) CV_OVERRIDE { (*alg_).setWarpingsNumber(val); }362inline double getEpsilon() const CV_OVERRIDE { return (*alg_).getEpsilon(); }363inline void setEpsilon(double val) CV_OVERRIDE { (*alg_).setEpsilon(val); }364inline int getIterations() const CV_OVERRIDE { return (*alg_).getOuterIterations(); }365inline void setIterations(int val) CV_OVERRIDE { (*alg_).setOuterIterations(val); }366inline bool getUseInitialFlow() const CV_OVERRIDE { return (*alg_).getUseInitialFlow(); }367inline void setUseInitialFlow(bool val) CV_OVERRIDE { (*alg_).setUseInitialFlow(val); }368369protected:370void impl(InputArray input0, InputArray input1, OutputArray dst) CV_OVERRIDE;371372private:373Ptr<cv::DualTVL1OpticalFlow> alg_;374};375376DualTVL1::DualTVL1() : CpuOpticalFlow(CV_8UC1)377{378alg_ = cv::createOptFlow_DualTVL1();379}380381void DualTVL1::calc(InputArray frame0, InputArray frame1, OutputArray flow1, OutputArray flow2)382{383CV_INSTRUMENT_REGION();384385CpuOpticalFlow::calc(frame0, frame1, flow1, flow2);386}387388void DualTVL1::impl(InputArray input0, InputArray input1, OutputArray dst)389{390alg_->calc(input0, input1, (InputOutputArray)dst);391}392393void DualTVL1::collectGarbage()394{395alg_->collectGarbage();396CpuOpticalFlow::collectGarbage();397}398}399400Ptr<cv::superres::DualTVL1OpticalFlow> cv::superres::createOptFlow_DualTVL1()401{402return makePtr<DualTVL1>();403}404405///////////////////////////////////////////////////////////////////406// GpuOpticalFlow407408#ifndef HAVE_OPENCV_CUDAOPTFLOW409410Ptr<cv::superres::FarnebackOpticalFlow> cv::superres::createOptFlow_Farneback_CUDA()411{412CV_Error(cv::Error::StsNotImplemented, "The called functionality is disabled for current build or platform");413}414415Ptr<cv::superres::DualTVL1OpticalFlow> cv::superres::createOptFlow_DualTVL1_CUDA()416{417CV_Error(cv::Error::StsNotImplemented, "The called functionality is disabled for current build or platform");418}419420Ptr<cv::superres::BroxOpticalFlow> cv::superres::createOptFlow_Brox_CUDA()421{422CV_Error(cv::Error::StsNotImplemented, "The called functionality is disabled for current build or platform");423}424425Ptr<cv::superres::PyrLKOpticalFlow> cv::superres::createOptFlow_PyrLK_CUDA()426{427CV_Error(cv::Error::StsNotImplemented, "The called functionality is disabled for current build or platform");428}429430#else // HAVE_OPENCV_CUDAOPTFLOW431432namespace433{434class GpuOpticalFlow : public virtual cv::superres::DenseOpticalFlowExt435{436public:437explicit GpuOpticalFlow(int work_type);438439void calc(InputArray frame0, InputArray frame1, OutputArray flow1, OutputArray flow2) CV_OVERRIDE;440void collectGarbage() CV_OVERRIDE;441442protected:443virtual void impl(const GpuMat& input0, const GpuMat& input1, GpuMat& dst1, GpuMat& dst2) = 0;444445private:446int work_type_;447GpuMat buf_[6];448GpuMat u_, v_, flow_;449};450451GpuOpticalFlow::GpuOpticalFlow(int work_type) : work_type_(work_type)452{453}454455void GpuOpticalFlow::calc(InputArray _frame0, InputArray _frame1, OutputArray _flow1, OutputArray _flow2)456{457CV_INSTRUMENT_REGION();458459GpuMat frame0 = arrGetGpuMat(_frame0, buf_[0]);460GpuMat frame1 = arrGetGpuMat(_frame1, buf_[1]);461462CV_Assert( frame1.type() == frame0.type() );463CV_Assert( frame1.size() == frame0.size() );464465GpuMat input0 = convertToType(frame0, work_type_, buf_[2], buf_[3]);466GpuMat input1 = convertToType(frame1, work_type_, buf_[4], buf_[5]);467468if (_flow2.needed() && _flow1.kind() == _InputArray::CUDA_GPU_MAT && _flow2.kind() == _InputArray::CUDA_GPU_MAT)469{470impl(input0, input1, _flow1.getGpuMatRef(), _flow2.getGpuMatRef());471return;472}473474impl(input0, input1, u_, v_);475476if (_flow2.needed())477{478arrCopy(u_, _flow1);479arrCopy(v_, _flow2);480}481else482{483GpuMat src[] = {u_, v_};484merge(src, 2, flow_);485arrCopy(flow_, _flow1);486}487}488489void GpuOpticalFlow::collectGarbage()490{491for (int i = 0; i < 6; ++i)492buf_[i].release();493u_.release();494v_.release();495flow_.release();496}497}498499///////////////////////////////////////////////////////////////////500// Brox_CUDA501502namespace503{504class Brox_CUDA : public GpuOpticalFlow, public virtual cv::superres::BroxOpticalFlow505{506public:507Brox_CUDA();508void calc(InputArray frame0, InputArray frame1, OutputArray flow1, OutputArray flow2) CV_OVERRIDE;509void collectGarbage() CV_OVERRIDE;510511inline double getAlpha() const CV_OVERRIDE { return alpha_; }512inline void setAlpha(double val) CV_OVERRIDE { alpha_ = val; }513inline double getGamma() const CV_OVERRIDE { return gamma_; }514inline void setGamma(double val) CV_OVERRIDE { gamma_ = val; }515inline double getScaleFactor() const CV_OVERRIDE { return scaleFactor_; }516inline void setScaleFactor(double val) CV_OVERRIDE { scaleFactor_ = val; }517inline int getInnerIterations() const CV_OVERRIDE { return innerIterations_; }518inline void setInnerIterations(int val) CV_OVERRIDE { innerIterations_ = val; }519inline int getOuterIterations() const CV_OVERRIDE { return outerIterations_; }520inline void setOuterIterations(int val) CV_OVERRIDE { outerIterations_ = val; }521inline int getSolverIterations() const CV_OVERRIDE { return solverIterations_; }522inline void setSolverIterations(int val) CV_OVERRIDE { solverIterations_ = val; }523524protected:525void impl(const GpuMat& input0, const GpuMat& input1, GpuMat& dst1, GpuMat& dst2) CV_OVERRIDE;526527private:528double alpha_;529double gamma_;530double scaleFactor_;531int innerIterations_;532int outerIterations_;533int solverIterations_;534535Ptr<cuda::BroxOpticalFlow> alg_;536};537538Brox_CUDA::Brox_CUDA() : GpuOpticalFlow(CV_32FC1)539{540alg_ = cuda::BroxOpticalFlow::create(0.197f, 50.0f, 0.8f, 10, 77, 10);541542alpha_ = alg_->getFlowSmoothness();543gamma_ = alg_->getGradientConstancyImportance();544scaleFactor_ = alg_->getPyramidScaleFactor();545innerIterations_ = alg_->getInnerIterations();546outerIterations_ = alg_->getOuterIterations();547solverIterations_ = alg_->getSolverIterations();548}549550void Brox_CUDA::calc(InputArray frame0, InputArray frame1, OutputArray flow1, OutputArray flow2)551{552GpuOpticalFlow::calc(frame0, frame1, flow1, flow2);553}554555void Brox_CUDA::impl(const GpuMat& input0, const GpuMat& input1, GpuMat& dst1, GpuMat& dst2)556{557alg_->setFlowSmoothness(alpha_);558alg_->setGradientConstancyImportance(gamma_);559alg_->setPyramidScaleFactor(scaleFactor_);560alg_->setInnerIterations(innerIterations_);561alg_->setOuterIterations(outerIterations_);562alg_->setSolverIterations(solverIterations_);563564GpuMat flow;565alg_->calc(input0, input1, flow);566567GpuMat flows[2];568cuda::split(flow, flows);569570dst1 = flows[0];571dst2 = flows[1];572}573574void Brox_CUDA::collectGarbage()575{576alg_ = cuda::BroxOpticalFlow::create(alpha_, gamma_, scaleFactor_, innerIterations_, outerIterations_, solverIterations_);577GpuOpticalFlow::collectGarbage();578}579}580581Ptr<cv::superres::BroxOpticalFlow> cv::superres::createOptFlow_Brox_CUDA()582{583return makePtr<Brox_CUDA>();584}585586///////////////////////////////////////////////////////////////////587// PyrLK_CUDA588589namespace590{591class PyrLK_CUDA : public GpuOpticalFlow, public cv::superres::PyrLKOpticalFlow592{593public:594PyrLK_CUDA();595void calc(InputArray frame0, InputArray frame1, OutputArray flow1, OutputArray flow2) CV_OVERRIDE;596void collectGarbage() CV_OVERRIDE;597598inline int getWindowSize() const CV_OVERRIDE { return winSize_; }599inline void setWindowSize(int val) CV_OVERRIDE { winSize_ = val; }600inline int getMaxLevel() const CV_OVERRIDE { return maxLevel_; }601inline void setMaxLevel(int val) CV_OVERRIDE { maxLevel_ = val; }602inline int getIterations() const CV_OVERRIDE { return iterations_; }603inline void setIterations(int val) CV_OVERRIDE { iterations_ = val; }604605protected:606void impl(const GpuMat& input0, const GpuMat& input1, GpuMat& dst1, GpuMat& dst2) CV_OVERRIDE;607608private:609int winSize_;610int maxLevel_;611int iterations_;612613Ptr<cuda::DensePyrLKOpticalFlow> alg_;614};615616PyrLK_CUDA::PyrLK_CUDA() : GpuOpticalFlow(CV_8UC1)617{618alg_ = cuda::DensePyrLKOpticalFlow::create();619620winSize_ = alg_->getWinSize().width;621maxLevel_ = alg_->getMaxLevel();622iterations_ = alg_->getNumIters();623}624625void PyrLK_CUDA::calc(InputArray frame0, InputArray frame1, OutputArray flow1, OutputArray flow2)626{627GpuOpticalFlow::calc(frame0, frame1, flow1, flow2);628}629630void PyrLK_CUDA::impl(const GpuMat& input0, const GpuMat& input1, GpuMat& dst1, GpuMat& dst2)631{632alg_->setWinSize(Size(winSize_, winSize_));633alg_->setMaxLevel(maxLevel_);634alg_->setNumIters(iterations_);635636GpuMat flow;637alg_->calc(input0, input1, flow);638639GpuMat flows[2];640cuda::split(flow, flows);641642dst1 = flows[0];643dst2 = flows[1];644}645646void PyrLK_CUDA::collectGarbage()647{648alg_ = cuda::DensePyrLKOpticalFlow::create();649GpuOpticalFlow::collectGarbage();650}651}652653Ptr<cv::superres::PyrLKOpticalFlow> cv::superres::createOptFlow_PyrLK_CUDA()654{655return makePtr<PyrLK_CUDA>();656}657658///////////////////////////////////////////////////////////////////659// Farneback_CUDA660661namespace662{663class Farneback_CUDA : public GpuOpticalFlow, public cv::superres::FarnebackOpticalFlow664{665public:666Farneback_CUDA();667void calc(InputArray frame0, InputArray frame1, OutputArray flow1, OutputArray flow2) CV_OVERRIDE;668void collectGarbage() CV_OVERRIDE;669670inline double getPyrScale() const CV_OVERRIDE { return pyrScale_; }671inline void setPyrScale(double val) CV_OVERRIDE { pyrScale_ = val; }672inline int getLevelsNumber() const CV_OVERRIDE { return numLevels_; }673inline void setLevelsNumber(int val) CV_OVERRIDE { numLevels_ = val; }674inline int getWindowSize() const CV_OVERRIDE { return winSize_; }675inline void setWindowSize(int val) CV_OVERRIDE { winSize_ = val; }676inline int getIterations() const CV_OVERRIDE { return numIters_; }677inline void setIterations(int val) CV_OVERRIDE { numIters_ = val; }678inline int getPolyN() const CV_OVERRIDE { return polyN_; }679inline void setPolyN(int val) CV_OVERRIDE { polyN_ = val; }680inline double getPolySigma() const CV_OVERRIDE { return polySigma_; }681inline void setPolySigma(double val) CV_OVERRIDE { polySigma_ = val; }682inline int getFlags() const CV_OVERRIDE { return flags_; }683inline void setFlags(int val) CV_OVERRIDE { flags_ = val; }684685protected:686void impl(const GpuMat& input0, const GpuMat& input1, GpuMat& dst1, GpuMat& dst2) CV_OVERRIDE;687688private:689double pyrScale_;690int numLevels_;691int winSize_;692int numIters_;693int polyN_;694double polySigma_;695int flags_;696697Ptr<cuda::FarnebackOpticalFlow> alg_;698};699700Farneback_CUDA::Farneback_CUDA() : GpuOpticalFlow(CV_8UC1)701{702alg_ = cuda::FarnebackOpticalFlow::create();703704pyrScale_ = alg_->getPyrScale();705numLevels_ = alg_->getNumLevels();706winSize_ = alg_->getWinSize();707numIters_ = alg_->getNumIters();708polyN_ = alg_->getPolyN();709polySigma_ = alg_->getPolySigma();710flags_ = alg_->getFlags();711}712713void Farneback_CUDA::calc(InputArray frame0, InputArray frame1, OutputArray flow1, OutputArray flow2)714{715GpuOpticalFlow::calc(frame0, frame1, flow1, flow2);716}717718void Farneback_CUDA::impl(const GpuMat& input0, const GpuMat& input1, GpuMat& dst1, GpuMat& dst2)719{720alg_->setPyrScale(pyrScale_);721alg_->setNumLevels(numLevels_);722alg_->setWinSize(winSize_);723alg_->setNumIters(numIters_);724alg_->setPolyN(polyN_);725alg_->setPolySigma(polySigma_);726alg_->setFlags(flags_);727728GpuMat flow;729alg_->calc(input0, input1, flow);730731GpuMat flows[2];732cuda::split(flow, flows);733734dst1 = flows[0];735dst2 = flows[1];736}737738void Farneback_CUDA::collectGarbage()739{740alg_ = cuda::FarnebackOpticalFlow::create();741GpuOpticalFlow::collectGarbage();742}743}744745Ptr<cv::superres::FarnebackOpticalFlow> cv::superres::createOptFlow_Farneback_CUDA()746{747return makePtr<Farneback_CUDA>();748}749750///////////////////////////////////////////////////////////////////751// DualTVL1_CUDA752753namespace754{755class DualTVL1_CUDA : public GpuOpticalFlow, public cv::superres::DualTVL1OpticalFlow756{757public:758DualTVL1_CUDA();759void calc(InputArray frame0, InputArray frame1, OutputArray flow1, OutputArray flow2) CV_OVERRIDE;760void collectGarbage() CV_OVERRIDE;761762inline double getTau() const CV_OVERRIDE { return tau_; }763inline void setTau(double val) CV_OVERRIDE { tau_ = val; }764inline double getLambda() const CV_OVERRIDE { return lambda_; }765inline void setLambda(double val) CV_OVERRIDE { lambda_ = val; }766inline double getTheta() const CV_OVERRIDE { return theta_; }767inline void setTheta(double val) CV_OVERRIDE { theta_ = val; }768inline int getScalesNumber() const CV_OVERRIDE { return nscales_; }769inline void setScalesNumber(int val) CV_OVERRIDE { nscales_ = val; }770inline int getWarpingsNumber() const CV_OVERRIDE { return warps_; }771inline void setWarpingsNumber(int val) CV_OVERRIDE { warps_ = val; }772inline double getEpsilon() const CV_OVERRIDE { return epsilon_; }773inline void setEpsilon(double val) CV_OVERRIDE { epsilon_ = val; }774inline int getIterations() const CV_OVERRIDE { return iterations_; }775inline void setIterations(int val) CV_OVERRIDE { iterations_ = val; }776inline bool getUseInitialFlow() const CV_OVERRIDE { return useInitialFlow_; }777inline void setUseInitialFlow(bool val) CV_OVERRIDE { useInitialFlow_ = val; }778779protected:780void impl(const GpuMat& input0, const GpuMat& input1, GpuMat& dst1, GpuMat& dst2) CV_OVERRIDE;781782private:783double tau_;784double lambda_;785double theta_;786int nscales_;787int warps_;788double epsilon_;789int iterations_;790bool useInitialFlow_;791792Ptr<cuda::OpticalFlowDual_TVL1> alg_;793};794795DualTVL1_CUDA::DualTVL1_CUDA() : GpuOpticalFlow(CV_8UC1)796{797alg_ = cuda::OpticalFlowDual_TVL1::create();798799tau_ = alg_->getTau();800lambda_ = alg_->getLambda();801theta_ = alg_->getTheta();802nscales_ = alg_->getNumScales();803warps_ = alg_->getNumWarps();804epsilon_ = alg_->getEpsilon();805iterations_ = alg_->getNumIterations();806useInitialFlow_ = alg_->getUseInitialFlow();807}808809void DualTVL1_CUDA::calc(InputArray frame0, InputArray frame1, OutputArray flow1, OutputArray flow2)810{811GpuOpticalFlow::calc(frame0, frame1, flow1, flow2);812}813814void DualTVL1_CUDA::impl(const GpuMat& input0, const GpuMat& input1, GpuMat& dst1, GpuMat& dst2)815{816alg_->setTau(tau_);817alg_->setLambda(lambda_);818alg_->setTheta(theta_);819alg_->setNumScales(nscales_);820alg_->setNumWarps(warps_);821alg_->setEpsilon(epsilon_);822alg_->setNumIterations(iterations_);823alg_->setUseInitialFlow(useInitialFlow_);824825GpuMat flow;826alg_->calc(input0, input1, flow);827828GpuMat flows[2];829cuda::split(flow, flows);830831dst1 = flows[0];832dst2 = flows[1];833}834835void DualTVL1_CUDA::collectGarbage()836{837alg_ = cuda::OpticalFlowDual_TVL1::create();838GpuOpticalFlow::collectGarbage();839}840}841842Ptr<cv::superres::DualTVL1OpticalFlow> cv::superres::createOptFlow_DualTVL1_CUDA()843{844return makePtr<DualTVL1_CUDA>();845}846847#endif // HAVE_OPENCV_CUDAOPTFLOW848849850