1 /*M///////////////////////////////////////////////////////////////////////////////////////
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install,
7 // copy or use the software.
11 // For Open Source Computer Vision Library
13 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
14 // Copyright (C) 2009, Willow Garage Inc., all rights reserved.
15 // Third party copyrights are property of their respective owners.
17 // Redistribution and use in source and binary forms, with or without modification,
18 // are permitted provided that the following conditions are met:
20 // * Redistribution's of source code must retain the above copyright notice,
21 // this list of conditions and the following disclaimer.
23 // * Redistribution's in binary form must reproduce the above copyright notice,
24 // this list of conditions and the following disclaimer in the documentation
25 // and/or other materials provided with the distribution.
27 // * The name of the copyright holders may not be used to endorse or promote products
28 // derived from this software without specific prior written permission.
30 // This software is provided by the copyright holders and contributors "as is" and
31 // any express or implied warranties, including, but not limited to, the implied
32 // warranties of merchantability and fitness for a particular purpose are disclaimed.
33 // In no event shall the Intel Corporation or contributors be liable for any direct,
34 // indirect, incidental, special, exemplary, or consequential damages
35 // (including, but not limited to, procurement of substitute goods or services;
36 // loss of use, data, or profits; or business interruption) however caused
37 // and on any theory of liability, whether in contract, strict liability,
38 // or tort (including negligence or otherwise) arising in any way out of
39 // the use of this software, even if advised of the possibility of such damage.
43 #include "precomp.hpp"
47 using namespace cv::gpu;
48 using namespace cv::superres;
49 using namespace cv::superres::detail;
51 ///////////////////////////////////////////////////////////////////
56 class CpuOpticalFlow : public DenseOpticalFlowExt
59 explicit CpuOpticalFlow(int work_type);
61 void calc(InputArray frame0, InputArray frame1, OutputArray flow1, OutputArray flow2);
62 void collectGarbage();
65 virtual void impl(const Mat& input0, const Mat& input1, OutputArray dst) = 0;
74 CpuOpticalFlow::CpuOpticalFlow(int work_type) : work_type_(work_type)
78 void CpuOpticalFlow::calc(InputArray _frame0, InputArray _frame1, OutputArray _flow1, OutputArray _flow2)
80 Mat frame0 = arrGetMat(_frame0, buf_[0]);
81 Mat frame1 = arrGetMat(_frame1, buf_[1]);
83 CV_Assert( frame1.type() == frame0.type() );
84 CV_Assert( frame1.size() == frame0.size() );
86 Mat input0 = convertToType(frame0, work_type_, buf_[2], buf_[3]);
87 Mat input1 = convertToType(frame1, work_type_, buf_[4], buf_[5]);
89 if (!_flow2.needed() && _flow1.kind() < _InputArray::OPENGL_BUFFER)
91 impl(input0, input1, _flow1);
95 impl(input0, input1, flow_);
99 arrCopy(flow_, _flow1);
103 split(flow_, flows_);
105 arrCopy(flows_[0], _flow1);
106 arrCopy(flows_[1], _flow2);
110 void CpuOpticalFlow::collectGarbage()
112 for (int i = 0; i < 6; ++i)
120 ///////////////////////////////////////////////////////////////////
125 class Farneback : public CpuOpticalFlow
128 AlgorithmInfo* info() const;
133 void impl(const Mat& input0, const Mat& input1, OutputArray dst);
145 CV_INIT_ALGORITHM(Farneback, "DenseOpticalFlowExt.Farneback",
146 obj.info()->addParam(obj, "pyrScale", obj.pyrScale_);
147 obj.info()->addParam(obj, "numLevels", obj.numLevels_);
148 obj.info()->addParam(obj, "winSize", obj.winSize_);
149 obj.info()->addParam(obj, "numIters", obj.numIters_);
150 obj.info()->addParam(obj, "polyN", obj.polyN_);
151 obj.info()->addParam(obj, "polySigma", obj.polySigma_);
152 obj.info()->addParam(obj, "flags", obj.flags_));
154 Farneback::Farneback() : CpuOpticalFlow(CV_8UC1)
165 void Farneback::impl(const Mat& input0, const Mat& input1, OutputArray dst)
167 calcOpticalFlowFarneback(input0, input1, dst, pyrScale_, numLevels_, winSize_, numIters_, polyN_, polySigma_, flags_);
171 Ptr<DenseOpticalFlowExt> cv::superres::createOptFlow_Farneback()
173 return new Farneback;
176 ///////////////////////////////////////////////////////////////////
181 class Simple : public CpuOpticalFlow
184 AlgorithmInfo* info() const;
189 void impl(const Mat& input0, const Mat& input1, OutputArray dst);
193 int averagingBlockSize_;
197 int postProcessWindow_;
198 double sigmaDistFix_;
199 double sigmaColorFix_;
201 int upscaleAveragingRadius_;
202 double upscaleSigmaDist_;
203 double upscaleSigmaColor_;
207 CV_INIT_ALGORITHM(Simple, "DenseOpticalFlowExt.Simple",
208 obj.info()->addParam(obj, "layers", obj.layers_);
209 obj.info()->addParam(obj, "averagingBlockSize", obj.averagingBlockSize_);
210 obj.info()->addParam(obj, "maxFlow", obj.maxFlow_);
211 obj.info()->addParam(obj, "sigmaDist", obj.sigmaDist_);
212 obj.info()->addParam(obj, "sigmaColor", obj.sigmaColor_);
213 obj.info()->addParam(obj, "postProcessWindow", obj.postProcessWindow_);
214 obj.info()->addParam(obj, "sigmaDistFix", obj.sigmaDistFix_);
215 obj.info()->addParam(obj, "sigmaColorFix", obj.sigmaColorFix_);
216 obj.info()->addParam(obj, "occThr", obj.occThr_);
217 obj.info()->addParam(obj, "upscaleAveragingRadius", obj.upscaleAveragingRadius_);
218 obj.info()->addParam(obj, "upscaleSigmaDist", obj.upscaleSigmaDist_);
219 obj.info()->addParam(obj, "upscaleSigmaColor", obj.upscaleSigmaColor_);
220 obj.info()->addParam(obj, "speedUpThr", obj.speedUpThr_));
222 Simple::Simple() : CpuOpticalFlow(CV_8UC3)
225 averagingBlockSize_ = 2;
229 postProcessWindow_ = 18;
230 sigmaDistFix_ = 55.0;
231 sigmaColorFix_ = 25.5;
233 upscaleAveragingRadius_ = 18;
234 upscaleSigmaDist_ = 55.0;
235 upscaleSigmaColor_ = 25.5;
239 void Simple::impl(const Mat& _input0, const Mat& _input1, OutputArray dst)
241 Mat input0 = _input0;
242 Mat input1 = _input1;
243 calcOpticalFlowSF(input0, input1, dst.getMatRef(),
253 upscaleAveragingRadius_,
260 Ptr<DenseOpticalFlowExt> cv::superres::createOptFlow_Simple()
265 ///////////////////////////////////////////////////////////////////
270 class DualTVL1 : public CpuOpticalFlow
273 AlgorithmInfo* info() const;
277 void collectGarbage();
280 void impl(const Mat& input0, const Mat& input1, OutputArray dst);
290 bool useInitialFlow_;
292 Ptr<DenseOpticalFlow> alg_;
295 CV_INIT_ALGORITHM(DualTVL1, "DenseOpticalFlowExt.DualTVL1",
296 obj.info()->addParam(obj, "tau", obj.tau_);
297 obj.info()->addParam(obj, "lambda", obj.lambda_);
298 obj.info()->addParam(obj, "theta", obj.theta_);
299 obj.info()->addParam(obj, "nscales", obj.nscales_);
300 obj.info()->addParam(obj, "warps", obj.warps_);
301 obj.info()->addParam(obj, "epsilon", obj.epsilon_);
302 obj.info()->addParam(obj, "iterations", obj.iterations_);
303 obj.info()->addParam(obj, "useInitialFlow", obj.useInitialFlow_));
305 DualTVL1::DualTVL1() : CpuOpticalFlow(CV_8UC1)
307 alg_ = cv::createOptFlow_DualTVL1();
308 tau_ = alg_->getDouble("tau");
309 lambda_ = alg_->getDouble("lambda");
310 theta_ = alg_->getDouble("theta");
311 nscales_ = alg_->getInt("nscales");
312 warps_ = alg_->getInt("warps");
313 epsilon_ = alg_->getDouble("epsilon");
314 iterations_ = alg_->getInt("iterations");
315 useInitialFlow_ = alg_->getBool("useInitialFlow");
318 void DualTVL1::impl(const Mat& input0, const Mat& input1, OutputArray dst)
320 alg_->set("tau", tau_);
321 alg_->set("lambda", lambda_);
322 alg_->set("theta", theta_);
323 alg_->set("nscales", nscales_);
324 alg_->set("warps", warps_);
325 alg_->set("epsilon", epsilon_);
326 alg_->set("iterations", iterations_);
327 alg_->set("useInitialFlow", useInitialFlow_);
329 alg_->calc(input0, input1, dst);
332 void DualTVL1::collectGarbage()
334 alg_->collectGarbage();
335 CpuOpticalFlow::collectGarbage();
339 Ptr<DenseOpticalFlowExt> cv::superres::createOptFlow_DualTVL1()
344 ///////////////////////////////////////////////////////////////////
347 #ifndef HAVE_OPENCV_GPU
349 Ptr<DenseOpticalFlowExt> cv::superres::createOptFlow_Farneback_GPU()
351 CV_Error(CV_StsNotImplemented, "The called functionality is disabled for current build or platform");
352 return Ptr<DenseOpticalFlowExt>();
355 Ptr<DenseOpticalFlowExt> cv::superres::createOptFlow_DualTVL1_GPU()
357 CV_Error(CV_StsNotImplemented, "The called functionality is disabled for current build or platform");
358 return Ptr<DenseOpticalFlowExt>();
361 Ptr<DenseOpticalFlowExt> cv::superres::createOptFlow_Brox_GPU()
363 CV_Error(CV_StsNotImplemented, "The called functionality is disabled for current build or platform");
364 return Ptr<DenseOpticalFlowExt>();
367 Ptr<DenseOpticalFlowExt> cv::superres::createOptFlow_PyrLK_GPU()
369 CV_Error(CV_StsNotImplemented, "The called functionality is disabled for current build or platform");
370 return Ptr<DenseOpticalFlowExt>();
373 #else // HAVE_OPENCV_GPU
377 class GpuOpticalFlow : public DenseOpticalFlowExt
380 explicit GpuOpticalFlow(int work_type);
382 void calc(InputArray frame0, InputArray frame1, OutputArray flow1, OutputArray flow2);
383 void collectGarbage();
386 virtual void impl(const GpuMat& input0, const GpuMat& input1, GpuMat& dst1, GpuMat& dst2) = 0;
391 GpuMat u_, v_, flow_;
394 GpuOpticalFlow::GpuOpticalFlow(int work_type) : work_type_(work_type)
398 void GpuOpticalFlow::calc(InputArray _frame0, InputArray _frame1, OutputArray _flow1, OutputArray _flow2)
400 GpuMat frame0 = arrGetGpuMat(_frame0, buf_[0]);
401 GpuMat frame1 = arrGetGpuMat(_frame1, buf_[1]);
403 CV_Assert( frame1.type() == frame0.type() );
404 CV_Assert( frame1.size() == frame0.size() );
406 GpuMat input0 = convertToType(frame0, work_type_, buf_[2], buf_[3]);
407 GpuMat input1 = convertToType(frame1, work_type_, buf_[4], buf_[5]);
409 if (_flow2.needed() && _flow1.kind() == _InputArray::GPU_MAT && _flow2.kind() == _InputArray::GPU_MAT)
411 impl(input0, input1, _flow1.getGpuMatRef(), _flow2.getGpuMatRef());
415 impl(input0, input1, u_, v_);
424 GpuMat src[] = {u_, v_};
425 merge(src, 2, flow_);
426 arrCopy(flow_, _flow1);
430 void GpuOpticalFlow::collectGarbage()
432 for (int i = 0; i < 6; ++i)
440 ///////////////////////////////////////////////////////////////////
445 class Brox_GPU : public GpuOpticalFlow
448 AlgorithmInfo* info() const;
452 void collectGarbage();
455 void impl(const GpuMat& input0, const GpuMat& input1, GpuMat& dst1, GpuMat& dst2);
461 int innerIterations_;
462 int outerIterations_;
463 int solverIterations_;
465 BroxOpticalFlow alg_;
468 CV_INIT_ALGORITHM(Brox_GPU, "DenseOpticalFlowExt.Brox_GPU",
469 obj.info()->addParam(obj, "alpha", obj.alpha_, false, 0, 0, "Flow smoothness");
470 obj.info()->addParam(obj, "gamma", obj.gamma_, false, 0, 0, "Gradient constancy importance");
471 obj.info()->addParam(obj, "scaleFactor", obj.scaleFactor_, false, 0, 0, "Pyramid scale factor");
472 obj.info()->addParam(obj, "innerIterations", obj.innerIterations_, false, 0, 0, "Number of lagged non-linearity iterations (inner loop)");
473 obj.info()->addParam(obj, "outerIterations", obj.outerIterations_, false, 0, 0, "Number of warping iterations (number of pyramid levels)");
474 obj.info()->addParam(obj, "solverIterations", obj.solverIterations_, false, 0, 0, "Number of linear system solver iterations"));
476 Brox_GPU::Brox_GPU() : GpuOpticalFlow(CV_32FC1), alg_(0.197f, 50.0f, 0.8f, 10, 77, 10)
480 scaleFactor_ = alg_.scale_factor;
481 innerIterations_ = alg_.inner_iterations;
482 outerIterations_ = alg_.outer_iterations;
483 solverIterations_ = alg_.solver_iterations;
486 void Brox_GPU::impl(const GpuMat& input0, const GpuMat& input1, GpuMat& dst1, GpuMat& dst2)
488 alg_.alpha = static_cast<float>(alpha_);
489 alg_.gamma = static_cast<float>(gamma_);
490 alg_.scale_factor = static_cast<float>(scaleFactor_);
491 alg_.inner_iterations = innerIterations_;
492 alg_.outer_iterations = outerIterations_;
493 alg_.solver_iterations = solverIterations_;
495 alg_(input0, input1, dst1, dst2);
498 void Brox_GPU::collectGarbage()
501 GpuOpticalFlow::collectGarbage();
505 Ptr<DenseOpticalFlowExt> cv::superres::createOptFlow_Brox_GPU()
510 ///////////////////////////////////////////////////////////////////
515 class PyrLK_GPU : public GpuOpticalFlow
518 AlgorithmInfo* info() const;
522 void collectGarbage();
525 void impl(const GpuMat& input0, const GpuMat& input1, GpuMat& dst1, GpuMat& dst2);
532 PyrLKOpticalFlow alg_;
535 CV_INIT_ALGORITHM(PyrLK_GPU, "DenseOpticalFlowExt.PyrLK_GPU",
536 obj.info()->addParam(obj, "winSize", obj.winSize_);
537 obj.info()->addParam(obj, "maxLevel", obj.maxLevel_);
538 obj.info()->addParam(obj, "iterations", obj.iterations_));
540 PyrLK_GPU::PyrLK_GPU() : GpuOpticalFlow(CV_8UC1)
542 winSize_ = alg_.winSize.width;
543 maxLevel_ = alg_.maxLevel;
544 iterations_ = alg_.iters;
547 void PyrLK_GPU::impl(const GpuMat& input0, const GpuMat& input1, GpuMat& dst1, GpuMat& dst2)
549 alg_.winSize.width = winSize_;
550 alg_.winSize.height = winSize_;
551 alg_.maxLevel = maxLevel_;
552 alg_.iters = iterations_;
554 alg_.dense(input0, input1, dst1, dst2);
557 void PyrLK_GPU::collectGarbage()
559 alg_.releaseMemory();
560 GpuOpticalFlow::collectGarbage();
564 Ptr<DenseOpticalFlowExt> cv::superres::createOptFlow_PyrLK_GPU()
566 return new PyrLK_GPU;
569 ///////////////////////////////////////////////////////////////////
574 class Farneback_GPU : public GpuOpticalFlow
577 AlgorithmInfo* info() const;
581 void collectGarbage();
584 void impl(const GpuMat& input0, const GpuMat& input1, GpuMat& dst1, GpuMat& dst2);
595 FarnebackOpticalFlow alg_;
598 CV_INIT_ALGORITHM(Farneback_GPU, "DenseOpticalFlowExt.Farneback_GPU",
599 obj.info()->addParam(obj, "pyrScale", obj.pyrScale_);
600 obj.info()->addParam(obj, "numLevels", obj.numLevels_);
601 obj.info()->addParam(obj, "winSize", obj.winSize_);
602 obj.info()->addParam(obj, "numIters", obj.numIters_);
603 obj.info()->addParam(obj, "polyN", obj.polyN_);
604 obj.info()->addParam(obj, "polySigma", obj.polySigma_);
605 obj.info()->addParam(obj, "flags", obj.flags_));
607 Farneback_GPU::Farneback_GPU() : GpuOpticalFlow(CV_8UC1)
609 pyrScale_ = alg_.pyrScale;
610 numLevels_ = alg_.numLevels;
611 winSize_ = alg_.winSize;
612 numIters_ = alg_.numIters;
614 polySigma_ = alg_.polySigma;
618 void Farneback_GPU::impl(const GpuMat& input0, const GpuMat& input1, GpuMat& dst1, GpuMat& dst2)
620 alg_.pyrScale = pyrScale_;
621 alg_.numLevels = numLevels_;
622 alg_.winSize = winSize_;
623 alg_.numIters = numIters_;
625 alg_.polySigma = polySigma_;
628 alg_(input0, input1, dst1, dst2);
631 void Farneback_GPU::collectGarbage()
633 alg_.releaseMemory();
634 GpuOpticalFlow::collectGarbage();
638 Ptr<DenseOpticalFlowExt> cv::superres::createOptFlow_Farneback_GPU()
640 return new Farneback_GPU;
643 ///////////////////////////////////////////////////////////////////
648 class DualTVL1_GPU : public GpuOpticalFlow
651 AlgorithmInfo* info() const;
655 void collectGarbage();
658 void impl(const GpuMat& input0, const GpuMat& input1, GpuMat& dst1, GpuMat& dst2);
668 bool useInitialFlow_;
670 OpticalFlowDual_TVL1_GPU alg_;
673 CV_INIT_ALGORITHM(DualTVL1_GPU, "DenseOpticalFlowExt.DualTVL1_GPU",
674 obj.info()->addParam(obj, "tau", obj.tau_);
675 obj.info()->addParam(obj, "lambda", obj.lambda_);
676 obj.info()->addParam(obj, "theta", obj.theta_);
677 obj.info()->addParam(obj, "nscales", obj.nscales_);
678 obj.info()->addParam(obj, "warps", obj.warps_);
679 obj.info()->addParam(obj, "epsilon", obj.epsilon_);
680 obj.info()->addParam(obj, "iterations", obj.iterations_);
681 obj.info()->addParam(obj, "useInitialFlow", obj.useInitialFlow_));
683 DualTVL1_GPU::DualTVL1_GPU() : GpuOpticalFlow(CV_8UC1)
686 lambda_ = alg_.lambda;
688 nscales_ = alg_.nscales;
690 epsilon_ = alg_.epsilon;
691 iterations_ = alg_.iterations;
692 useInitialFlow_ = alg_.useInitialFlow;
695 void DualTVL1_GPU::impl(const GpuMat& input0, const GpuMat& input1, GpuMat& dst1, GpuMat& dst2)
698 alg_.lambda = lambda_;
700 alg_.nscales = nscales_;
702 alg_.epsilon = epsilon_;
703 alg_.iterations = iterations_;
704 alg_.useInitialFlow = useInitialFlow_;
706 alg_(input0, input1, dst1, dst2);
709 void DualTVL1_GPU::collectGarbage()
711 alg_.collectGarbage();
712 GpuOpticalFlow::collectGarbage();
716 Ptr<DenseOpticalFlowExt> cv::superres::createOptFlow_DualTVL1_GPU()
718 return new DualTVL1_GPU;
721 #endif // HAVE_OPENCV_GPU