Merge pull request #1263 from abidrahmank:pyCLAHE_24
[profile/ivi/opencv.git] / modules / superres / src / optical_flow.cpp
1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
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.
8 //
9 //
10 //                           License Agreement
11 //                For Open Source Computer Vision Library
12 //
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.
16 //
17 // Redistribution and use in source and binary forms, with or without modification,
18 // are permitted provided that the following conditions are met:
19 //
20 //   * Redistribution's of source code must retain the above copyright notice,
21 //     this list of conditions and the following disclaimer.
22 //
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.
26 //
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.
29 //
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.
40 //
41 //M*/
42
43 #include "precomp.hpp"
44
45 using namespace std;
46 using namespace cv;
47 using namespace cv::gpu;
48 using namespace cv::superres;
49 using namespace cv::superres::detail;
50
51 ///////////////////////////////////////////////////////////////////
52 // CpuOpticalFlow
53
54 namespace
55 {
56     class CpuOpticalFlow : public DenseOpticalFlowExt
57     {
58     public:
59         explicit CpuOpticalFlow(int work_type);
60
61         void calc(InputArray frame0, InputArray frame1, OutputArray flow1, OutputArray flow2);
62         void collectGarbage();
63
64     protected:
65         virtual void impl(const Mat& input0, const Mat& input1, OutputArray dst) = 0;
66
67     private:
68         int work_type_;
69         Mat buf_[6];
70         Mat flow_;
71         Mat flows_[2];
72     };
73
74     CpuOpticalFlow::CpuOpticalFlow(int work_type) : work_type_(work_type)
75     {
76     }
77
78     void CpuOpticalFlow::calc(InputArray _frame0, InputArray _frame1, OutputArray _flow1, OutputArray _flow2)
79     {
80         Mat frame0 = arrGetMat(_frame0, buf_[0]);
81         Mat frame1 = arrGetMat(_frame1, buf_[1]);
82
83         CV_Assert( frame1.type() == frame0.type() );
84         CV_Assert( frame1.size() == frame0.size() );
85
86         Mat input0 = convertToType(frame0, work_type_, buf_[2], buf_[3]);
87         Mat input1 = convertToType(frame1, work_type_, buf_[4], buf_[5]);
88
89         if (!_flow2.needed() && _flow1.kind() < _InputArray::OPENGL_BUFFER)
90         {
91             impl(input0, input1, _flow1);
92             return;
93         }
94
95         impl(input0, input1, flow_);
96
97         if (!_flow2.needed())
98         {
99             arrCopy(flow_, _flow1);
100         }
101         else
102         {
103             split(flow_, flows_);
104
105             arrCopy(flows_[0], _flow1);
106             arrCopy(flows_[1], _flow2);
107         }
108     }
109
110     void CpuOpticalFlow::collectGarbage()
111     {
112         for (int i = 0; i < 6; ++i)
113             buf_[i].release();
114         flow_.release();
115         flows_[0].release();
116         flows_[1].release();
117     }
118 }
119
120 ///////////////////////////////////////////////////////////////////
121 // Farneback
122
123 namespace
124 {
125     class Farneback : public CpuOpticalFlow
126     {
127     public:
128         AlgorithmInfo* info() const;
129
130         Farneback();
131
132     protected:
133         void impl(const Mat& input0, const Mat& input1, OutputArray dst);
134
135     private:
136         double pyrScale_;
137         int numLevels_;
138         int winSize_;
139         int numIters_;
140         int polyN_;
141         double polySigma_;
142         int flags_;
143     };
144
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_));
153
154     Farneback::Farneback() : CpuOpticalFlow(CV_8UC1)
155     {
156         pyrScale_ = 0.5;
157         numLevels_ = 5;
158         winSize_ = 13;
159         numIters_ = 10;
160         polyN_ = 5;
161         polySigma_ = 1.1;
162         flags_ = 0;
163     }
164
165     void Farneback::impl(const Mat& input0, const Mat& input1, OutputArray dst)
166     {
167         calcOpticalFlowFarneback(input0, input1, dst, pyrScale_, numLevels_, winSize_, numIters_, polyN_, polySigma_, flags_);
168     }
169 }
170
171 Ptr<DenseOpticalFlowExt> cv::superres::createOptFlow_Farneback()
172 {
173     return new Farneback;
174 }
175
176 ///////////////////////////////////////////////////////////////////
177 // Simple
178
179 namespace
180 {
181     class Simple : public CpuOpticalFlow
182     {
183     public:
184         AlgorithmInfo* info() const;
185
186         Simple();
187
188     protected:
189         void impl(const Mat& input0, const Mat& input1, OutputArray dst);
190
191     private:
192         int layers_;
193         int averagingBlockSize_;
194         int maxFlow_;
195         double sigmaDist_;
196         double sigmaColor_;
197         int postProcessWindow_;
198         double sigmaDistFix_;
199         double sigmaColorFix_;
200         double occThr_;
201         int upscaleAveragingRadius_;
202         double upscaleSigmaDist_;
203         double upscaleSigmaColor_;
204         double speedUpThr_;
205     };
206
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_));
221
222     Simple::Simple() : CpuOpticalFlow(CV_8UC3)
223     {
224         layers_ = 3;
225         averagingBlockSize_ = 2;
226         maxFlow_ = 4;
227         sigmaDist_ = 4.1;
228         sigmaColor_ = 25.5;
229         postProcessWindow_ = 18;
230         sigmaDistFix_ = 55.0;
231         sigmaColorFix_ = 25.5;
232         occThr_ = 0.35;
233         upscaleAveragingRadius_ = 18;
234         upscaleSigmaDist_ = 55.0;
235         upscaleSigmaColor_ = 25.5;
236         speedUpThr_ = 10;
237     }
238
239     void Simple::impl(const Mat& _input0, const Mat& _input1, OutputArray dst)
240     {
241         Mat input0 = _input0;
242         Mat input1 = _input1;
243         calcOpticalFlowSF(input0, input1, dst.getMatRef(),
244                           layers_,
245                           averagingBlockSize_,
246                           maxFlow_,
247                           sigmaDist_,
248                           sigmaColor_,
249                           postProcessWindow_,
250                           sigmaDistFix_,
251                           sigmaColorFix_,
252                           occThr_,
253                           upscaleAveragingRadius_,
254                           upscaleSigmaDist_,
255                           upscaleSigmaColor_,
256                           speedUpThr_);
257     }
258 }
259
260 Ptr<DenseOpticalFlowExt> cv::superres::createOptFlow_Simple()
261 {
262     return new Simple;
263 }
264
265 ///////////////////////////////////////////////////////////////////
266 // DualTVL1
267
268 namespace
269 {
270     class DualTVL1 : public CpuOpticalFlow
271     {
272     public:
273         AlgorithmInfo* info() const;
274
275         DualTVL1();
276
277         void collectGarbage();
278
279     protected:
280         void impl(const Mat& input0, const Mat& input1, OutputArray dst);
281
282     private:
283         double tau_;
284         double lambda_;
285         double theta_;
286         int nscales_;
287         int warps_;
288         double epsilon_;
289         int iterations_;
290         bool useInitialFlow_;
291
292         Ptr<DenseOpticalFlow> alg_;
293     };
294
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_));
304
305     DualTVL1::DualTVL1() : CpuOpticalFlow(CV_8UC1)
306     {
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");
316     }
317
318     void DualTVL1::impl(const Mat& input0, const Mat& input1, OutputArray dst)
319     {
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_);
328
329         alg_->calc(input0, input1, dst);
330     }
331
332     void DualTVL1::collectGarbage()
333     {
334         alg_->collectGarbage();
335         CpuOpticalFlow::collectGarbage();
336     }
337 }
338
339 Ptr<DenseOpticalFlowExt> cv::superres::createOptFlow_DualTVL1()
340 {
341     return new DualTVL1;
342 }
343
344 ///////////////////////////////////////////////////////////////////
345 // GpuOpticalFlow
346
347 #ifndef HAVE_OPENCV_GPU
348
349 Ptr<DenseOpticalFlowExt> cv::superres::createOptFlow_Farneback_GPU()
350 {
351     CV_Error(CV_StsNotImplemented, "The called functionality is disabled for current build or platform");
352     return Ptr<DenseOpticalFlowExt>();
353 }
354
355 Ptr<DenseOpticalFlowExt> cv::superres::createOptFlow_DualTVL1_GPU()
356 {
357     CV_Error(CV_StsNotImplemented, "The called functionality is disabled for current build or platform");
358     return Ptr<DenseOpticalFlowExt>();
359 }
360
361 Ptr<DenseOpticalFlowExt> cv::superres::createOptFlow_Brox_GPU()
362 {
363     CV_Error(CV_StsNotImplemented, "The called functionality is disabled for current build or platform");
364     return Ptr<DenseOpticalFlowExt>();
365 }
366
367 Ptr<DenseOpticalFlowExt> cv::superres::createOptFlow_PyrLK_GPU()
368 {
369     CV_Error(CV_StsNotImplemented, "The called functionality is disabled for current build or platform");
370     return Ptr<DenseOpticalFlowExt>();
371 }
372
373 #else // HAVE_OPENCV_GPU
374
375 namespace
376 {
377     class GpuOpticalFlow : public DenseOpticalFlowExt
378     {
379     public:
380         explicit GpuOpticalFlow(int work_type);
381
382         void calc(InputArray frame0, InputArray frame1, OutputArray flow1, OutputArray flow2);
383         void collectGarbage();
384
385     protected:
386         virtual void impl(const GpuMat& input0, const GpuMat& input1, GpuMat& dst1, GpuMat& dst2) = 0;
387
388     private:
389         int work_type_;
390         GpuMat buf_[6];
391         GpuMat u_, v_, flow_;
392     };
393
394     GpuOpticalFlow::GpuOpticalFlow(int work_type) : work_type_(work_type)
395     {
396     }
397
398     void GpuOpticalFlow::calc(InputArray _frame0, InputArray _frame1, OutputArray _flow1, OutputArray _flow2)
399     {
400         GpuMat frame0 = arrGetGpuMat(_frame0, buf_[0]);
401         GpuMat frame1 = arrGetGpuMat(_frame1, buf_[1]);
402
403         CV_Assert( frame1.type() == frame0.type() );
404         CV_Assert( frame1.size() == frame0.size() );
405
406         GpuMat input0 = convertToType(frame0, work_type_, buf_[2], buf_[3]);
407         GpuMat input1 = convertToType(frame1, work_type_, buf_[4], buf_[5]);
408
409         if (_flow2.needed() && _flow1.kind() == _InputArray::GPU_MAT && _flow2.kind() == _InputArray::GPU_MAT)
410         {
411             impl(input0, input1, _flow1.getGpuMatRef(), _flow2.getGpuMatRef());
412             return;
413         }
414
415         impl(input0, input1, u_, v_);
416
417         if (_flow2.needed())
418         {
419             arrCopy(u_, _flow1);
420             arrCopy(v_, _flow2);
421         }
422         else
423         {
424             GpuMat src[] = {u_, v_};
425             merge(src, 2, flow_);
426             arrCopy(flow_, _flow1);
427         }
428     }
429
430     void GpuOpticalFlow::collectGarbage()
431     {
432         for (int i = 0; i < 6; ++i)
433             buf_[i].release();
434         u_.release();
435         v_.release();
436         flow_.release();
437     }
438 }
439
440 ///////////////////////////////////////////////////////////////////
441 // Brox_GPU
442
443 namespace
444 {
445     class Brox_GPU : public GpuOpticalFlow
446     {
447     public:
448         AlgorithmInfo* info() const;
449
450         Brox_GPU();
451
452         void collectGarbage();
453
454     protected:
455         void impl(const GpuMat& input0, const GpuMat& input1, GpuMat& dst1, GpuMat& dst2);
456
457     private:
458         double alpha_;
459         double gamma_;
460         double scaleFactor_;
461         int innerIterations_;
462         int outerIterations_;
463         int solverIterations_;
464
465         BroxOpticalFlow alg_;
466     };
467
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"));
475
476     Brox_GPU::Brox_GPU() : GpuOpticalFlow(CV_32FC1), alg_(0.197f, 50.0f, 0.8f, 10, 77, 10)
477     {
478         alpha_ = alg_.alpha;
479         gamma_ = alg_.gamma;
480         scaleFactor_ = alg_.scale_factor;
481         innerIterations_ = alg_.inner_iterations;
482         outerIterations_ = alg_.outer_iterations;
483         solverIterations_ = alg_.solver_iterations;
484     }
485
486     void Brox_GPU::impl(const GpuMat& input0, const GpuMat& input1, GpuMat& dst1, GpuMat& dst2)
487     {
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_;
494
495         alg_(input0, input1, dst1, dst2);
496     }
497
498     void Brox_GPU::collectGarbage()
499     {
500         alg_.buf.release();
501         GpuOpticalFlow::collectGarbage();
502     }
503 }
504
505 Ptr<DenseOpticalFlowExt> cv::superres::createOptFlow_Brox_GPU()
506 {
507     return new Brox_GPU;
508 }
509
510 ///////////////////////////////////////////////////////////////////
511 // PyrLK_GPU
512
513 namespace
514 {
515     class PyrLK_GPU : public GpuOpticalFlow
516     {
517     public:
518         AlgorithmInfo* info() const;
519
520         PyrLK_GPU();
521
522         void collectGarbage();
523
524     protected:
525         void impl(const GpuMat& input0, const GpuMat& input1, GpuMat& dst1, GpuMat& dst2);
526
527     private:
528         int winSize_;
529         int maxLevel_;
530         int iterations_;
531
532         PyrLKOpticalFlow alg_;
533     };
534
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_));
539
540     PyrLK_GPU::PyrLK_GPU() : GpuOpticalFlow(CV_8UC1)
541     {
542         winSize_ = alg_.winSize.width;
543         maxLevel_ = alg_.maxLevel;
544         iterations_ = alg_.iters;
545     }
546
547     void PyrLK_GPU::impl(const GpuMat& input0, const GpuMat& input1, GpuMat& dst1, GpuMat& dst2)
548     {
549         alg_.winSize.width = winSize_;
550         alg_.winSize.height = winSize_;
551         alg_.maxLevel = maxLevel_;
552         alg_.iters = iterations_;
553
554         alg_.dense(input0, input1, dst1, dst2);
555     }
556
557     void PyrLK_GPU::collectGarbage()
558     {
559         alg_.releaseMemory();
560         GpuOpticalFlow::collectGarbage();
561     }
562 }
563
564 Ptr<DenseOpticalFlowExt> cv::superres::createOptFlow_PyrLK_GPU()
565 {
566     return new PyrLK_GPU;
567 }
568
569 ///////////////////////////////////////////////////////////////////
570 // Farneback_GPU
571
572 namespace
573 {
574     class Farneback_GPU : public GpuOpticalFlow
575     {
576     public:
577         AlgorithmInfo* info() const;
578
579         Farneback_GPU();
580
581         void collectGarbage();
582
583     protected:
584         void impl(const GpuMat& input0, const GpuMat& input1, GpuMat& dst1, GpuMat& dst2);
585
586     private:
587         double pyrScale_;
588         int numLevels_;
589         int winSize_;
590         int numIters_;
591         int polyN_;
592         double polySigma_;
593         int flags_;
594
595         FarnebackOpticalFlow alg_;
596     };
597
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_));
606
607     Farneback_GPU::Farneback_GPU() : GpuOpticalFlow(CV_8UC1)
608     {
609         pyrScale_ = alg_.pyrScale;
610         numLevels_ = alg_.numLevels;
611         winSize_ = alg_.winSize;
612         numIters_ = alg_.numIters;
613         polyN_ = alg_.polyN;
614         polySigma_ = alg_.polySigma;
615         flags_ = alg_.flags;
616     }
617
618     void Farneback_GPU::impl(const GpuMat& input0, const GpuMat& input1, GpuMat& dst1, GpuMat& dst2)
619     {
620         alg_.pyrScale = pyrScale_;
621         alg_.numLevels = numLevels_;
622         alg_.winSize = winSize_;
623         alg_.numIters = numIters_;
624         alg_.polyN = polyN_;
625         alg_.polySigma = polySigma_;
626         alg_.flags = flags_;
627
628         alg_(input0, input1, dst1, dst2);
629     }
630
631     void Farneback_GPU::collectGarbage()
632     {
633         alg_.releaseMemory();
634         GpuOpticalFlow::collectGarbage();
635     }
636 }
637
638 Ptr<DenseOpticalFlowExt> cv::superres::createOptFlow_Farneback_GPU()
639 {
640     return new Farneback_GPU;
641 }
642
643 ///////////////////////////////////////////////////////////////////
644 // DualTVL1_GPU
645
646 namespace
647 {
648     class DualTVL1_GPU : public GpuOpticalFlow
649     {
650     public:
651         AlgorithmInfo* info() const;
652
653         DualTVL1_GPU();
654
655         void collectGarbage();
656
657     protected:
658         void impl(const GpuMat& input0, const GpuMat& input1, GpuMat& dst1, GpuMat& dst2);
659
660     private:
661         double tau_;
662         double lambda_;
663         double theta_;
664         int nscales_;
665         int warps_;
666         double epsilon_;
667         int iterations_;
668         bool useInitialFlow_;
669
670         OpticalFlowDual_TVL1_GPU alg_;
671     };
672
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_));
682
683     DualTVL1_GPU::DualTVL1_GPU() : GpuOpticalFlow(CV_8UC1)
684     {
685         tau_ = alg_.tau;
686         lambda_ = alg_.lambda;
687         theta_ = alg_.theta;
688         nscales_ = alg_.nscales;
689         warps_ = alg_.warps;
690         epsilon_ = alg_.epsilon;
691         iterations_ = alg_.iterations;
692         useInitialFlow_ = alg_.useInitialFlow;
693     }
694
695     void DualTVL1_GPU::impl(const GpuMat& input0, const GpuMat& input1, GpuMat& dst1, GpuMat& dst2)
696     {
697         alg_.tau = tau_;
698         alg_.lambda = lambda_;
699         alg_.theta = theta_;
700         alg_.nscales = nscales_;
701         alg_.warps = warps_;
702         alg_.epsilon = epsilon_;
703         alg_.iterations = iterations_;
704         alg_.useInitialFlow = useInitialFlow_;
705
706         alg_(input0, input1, dst1, dst2);
707     }
708
709     void DualTVL1_GPU::collectGarbage()
710     {
711         alg_.collectGarbage();
712         GpuOpticalFlow::collectGarbage();
713     }
714 }
715
716 Ptr<DenseOpticalFlowExt> cv::superres::createOptFlow_DualTVL1_GPU()
717 {
718     return new DualTVL1_GPU;
719 }
720
721 #endif // HAVE_OPENCV_GPU
722 #ifdef HAVE_OPENCV_OCL
723
724 namespace
725 {
726     class oclOpticalFlow : public DenseOpticalFlowExt
727     {
728     public:
729         explicit oclOpticalFlow(int work_type);
730
731         void calc(InputArray frame0, InputArray frame1, OutputArray flow1, OutputArray flow2);
732         void collectGarbage();
733
734     protected:
735         virtual void impl(const cv::ocl::oclMat& input0, const cv::ocl::oclMat& input1, cv::ocl::oclMat& dst1, cv::ocl::oclMat& dst2) = 0;
736
737     private:
738         int work_type_;
739         cv::ocl::oclMat buf_[6];
740         cv::ocl::oclMat u_, v_, flow_;
741     };
742
743     oclOpticalFlow::oclOpticalFlow(int work_type) : work_type_(work_type)
744     {
745     }
746
747     void oclOpticalFlow::calc(InputArray frame0, InputArray frame1, OutputArray flow1, OutputArray flow2)
748     {
749         ocl::oclMat& _frame0 = ocl::getOclMatRef(frame0);
750         ocl::oclMat& _frame1 = ocl::getOclMatRef(frame1);
751         ocl::oclMat& _flow1  = ocl::getOclMatRef(flow1);
752         ocl::oclMat& _flow2  = ocl::getOclMatRef(flow2);
753
754         CV_Assert( _frame1.type() == _frame0.type() );
755         CV_Assert( _frame1.size() == _frame0.size() );
756
757         cv::ocl::oclMat input0_ = convertToType(_frame0, work_type_, buf_[2], buf_[3]);
758         cv::ocl::oclMat input1_ = convertToType(_frame1, work_type_, buf_[4], buf_[5]);
759
760         impl(input0_, input1_, u_, v_);//go to tvl1 algorithm
761
762         u_.copyTo(_flow1);
763         v_.copyTo(_flow2);
764     }
765
766     void oclOpticalFlow::collectGarbage()
767     {
768         for (int i = 0; i < 6; ++i)
769             buf_[i].release();
770         u_.release();
771         v_.release();
772         flow_.release();
773     }
774 }
775 ///////////////////////////////////////////////////////////////////
776 // PyrLK_OCL
777
778 namespace
779 {
780     class PyrLK_OCL : public oclOpticalFlow
781     {
782     public:
783         AlgorithmInfo* info() const;
784
785         PyrLK_OCL();
786
787         void collectGarbage();
788
789     protected:
790         void impl(const ocl::oclMat& input0, const ocl::oclMat& input1, ocl::oclMat& dst1, ocl::oclMat& dst2);
791
792     private:
793         int winSize_;
794         int maxLevel_;
795         int iterations_;
796
797         ocl::PyrLKOpticalFlow alg_;
798     };
799
800     CV_INIT_ALGORITHM(PyrLK_OCL, "DenseOpticalFlowExt.PyrLK_OCL",
801         obj.info()->addParam(obj, "winSize", obj.winSize_);
802     obj.info()->addParam(obj, "maxLevel", obj.maxLevel_);
803     obj.info()->addParam(obj, "iterations", obj.iterations_));
804
805     PyrLK_OCL::PyrLK_OCL() : oclOpticalFlow(CV_8UC1)
806     {
807         winSize_ = alg_.winSize.width;
808         maxLevel_ = alg_.maxLevel;
809         iterations_ = alg_.iters;
810     }
811
812     void PyrLK_OCL::impl(const cv::ocl::oclMat& input0, const cv::ocl::oclMat& input1, cv::ocl::oclMat& dst1, cv::ocl::oclMat& dst2)
813     {
814         alg_.winSize.width = winSize_;
815         alg_.winSize.height = winSize_;
816         alg_.maxLevel = maxLevel_;
817         alg_.iters = iterations_;
818
819         alg_.dense(input0, input1, dst1, dst2);
820     }
821
822     void PyrLK_OCL::collectGarbage()
823     {
824         alg_.releaseMemory();
825         oclOpticalFlow::collectGarbage();
826     }
827 }
828
829 Ptr<DenseOpticalFlowExt> cv::superres::createOptFlow_PyrLK_OCL()
830 {
831     return new PyrLK_OCL;
832 }
833
834 ///////////////////////////////////////////////////////////////////
835 // DualTVL1_OCL
836
837 namespace
838 {
839     class DualTVL1_OCL : public oclOpticalFlow
840     {
841     public:
842         AlgorithmInfo* info() const;
843
844         DualTVL1_OCL();
845
846         void collectGarbage();
847
848     protected:
849         void impl(const cv::ocl::oclMat& input0, const cv::ocl::oclMat& input1, cv::ocl::oclMat& dst1, cv::ocl::oclMat& dst2);
850
851     private:
852         double tau_;
853         double lambda_;
854         double theta_;
855         int nscales_;
856         int warps_;
857         double epsilon_;
858         int iterations_;
859         bool useInitialFlow_;
860
861         ocl::OpticalFlowDual_TVL1_OCL alg_;
862     };
863
864     CV_INIT_ALGORITHM(DualTVL1_OCL, "DenseOpticalFlowExt.DualTVL1_OCL",
865     obj.info()->addParam(obj, "tau", obj.tau_);
866     obj.info()->addParam(obj, "lambda", obj.lambda_);
867     obj.info()->addParam(obj, "theta", obj.theta_);
868     obj.info()->addParam(obj, "nscales", obj.nscales_);
869     obj.info()->addParam(obj, "warps", obj.warps_);
870     obj.info()->addParam(obj, "epsilon", obj.epsilon_);
871     obj.info()->addParam(obj, "iterations", obj.iterations_);
872     obj.info()->addParam(obj, "useInitialFlow", obj.useInitialFlow_));
873
874     DualTVL1_OCL::DualTVL1_OCL() : oclOpticalFlow(CV_8UC1)
875     {
876         tau_ = alg_.tau;
877         lambda_ = alg_.lambda;
878         theta_ = alg_.theta;
879         nscales_ = alg_.nscales;
880         warps_ = alg_.warps;
881         epsilon_ = alg_.epsilon;
882         iterations_ = alg_.iterations;
883         useInitialFlow_ = alg_.useInitialFlow;
884     }
885
886     void DualTVL1_OCL::impl(const cv::ocl::oclMat& input0, const cv::ocl::oclMat& input1, cv::ocl::oclMat& dst1, cv::ocl::oclMat& dst2)
887     {
888         alg_.tau = tau_;
889         alg_.lambda = lambda_;
890         alg_.theta = theta_;
891         alg_.nscales = nscales_;
892         alg_.warps = warps_;
893         alg_.epsilon = epsilon_;
894         alg_.iterations = iterations_;
895         alg_.useInitialFlow = useInitialFlow_;
896
897         alg_(input0, input1, dst1, dst2);
898
899     }
900
901     void DualTVL1_OCL::collectGarbage()
902     {
903         alg_.collectGarbage();
904         oclOpticalFlow::collectGarbage();
905     }
906 }
907
908 Ptr<DenseOpticalFlowExt> cv::superres::createOptFlow_DualTVL1_OCL()
909 {
910     return new DualTVL1_OCL;
911 }
912
913 ///////////////////////////////////////////////////////////////////
914 // FarneBack
915
916 namespace
917 {
918     class FarneBack_OCL : public oclOpticalFlow
919     {
920     public:
921         AlgorithmInfo* info() const;
922
923         FarneBack_OCL();
924
925         void collectGarbage();
926
927     protected:
928         void impl(const cv::ocl::oclMat& input0, const cv::ocl::oclMat& input1, cv::ocl::oclMat& dst1, cv::ocl::oclMat& dst2);
929
930     private:
931         double pyrScale_;
932         int numLevels_;
933         int winSize_;
934         int numIters_;
935         int polyN_;
936         double polySigma_;
937         int flags_;
938
939         ocl::FarnebackOpticalFlow alg_;
940     };
941
942     CV_INIT_ALGORITHM(FarneBack_OCL, "DenseOpticalFlowExt.FarneBack_OCL",
943         obj.info()->addParam(obj, "pyrScale", obj.pyrScale_);
944     obj.info()->addParam(obj, "numLevels", obj.numLevels_);
945     obj.info()->addParam(obj, "winSize", obj.winSize_);
946     obj.info()->addParam(obj, "numIters", obj.numIters_);
947     obj.info()->addParam(obj, "polyN", obj.polyN_);
948     obj.info()->addParam(obj, "polySigma", obj.polySigma_);
949     obj.info()->addParam(obj, "flags", obj.flags_));
950
951     FarneBack_OCL::FarneBack_OCL() : oclOpticalFlow(CV_8UC1)
952     {
953         pyrScale_ = alg_.pyrScale;
954         numLevels_ = alg_.numLevels;
955         winSize_ = alg_.winSize;
956         numIters_ = alg_.numIters;
957         polyN_ = alg_.polyN;
958         polySigma_ = alg_.polySigma;
959         flags_ = alg_.flags;
960     }
961
962     void FarneBack_OCL::impl(const cv::ocl::oclMat& input0, const cv::ocl::oclMat& input1, cv::ocl::oclMat& dst1, cv::ocl::oclMat& dst2)
963     {
964         alg_.pyrScale = pyrScale_;
965         alg_.numLevels = numLevels_;
966         alg_.winSize = winSize_;
967         alg_.numIters = numIters_;
968         alg_.polyN = polyN_;
969         alg_.polySigma = polySigma_;
970         alg_.flags = flags_;
971
972         alg_(input0, input1, dst1, dst2);
973     }
974
975     void FarneBack_OCL::collectGarbage()
976     {
977         alg_.releaseMemory();
978         oclOpticalFlow::collectGarbage();
979     }
980 }
981
982 Ptr<DenseOpticalFlowExt> cv::superres::createOptFlow_Farneback_OCL()
983 {
984     return new FarneBack_OCL;
985 }
986
987 #endif