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 #include "opencv2/core/opencl/ocl_defs.hpp"
45 
46 using namespace cv;
47 using namespace cv::cuda;
48 using namespace cv::superres;
49 using namespace cv::superres::detail;
50 
51 ///////////////////////////////////////////////////////////////////
52 // CpuOpticalFlow
53 
54 namespace
55 {
56     class CpuOpticalFlow : public virtual cv::superres::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(InputArray input0, InputArray input1, OutputArray dst) = 0;
66 
67     private:
68         bool ocl_calc(InputArray frame0, InputArray frame1, OutputArray flow1, OutputArray flow2);
69 
70         int work_type_;
71 
72         // Mat
73         Mat buf_[6];
74         Mat flow_;
75         Mat flows_[2];
76 
77         // UMat
78         UMat ubuf_[6];
79         UMat uflow_;
80         std::vector<UMat> uflows_;
81     };
82 
CpuOpticalFlow(int work_type)83     CpuOpticalFlow::CpuOpticalFlow(int work_type) :
84         work_type_(work_type)
85     {
86     }
87 
ocl_calc(InputArray _frame0,InputArray _frame1,OutputArray _flow1,OutputArray _flow2)88     bool CpuOpticalFlow::ocl_calc(InputArray _frame0, InputArray _frame1, OutputArray _flow1, OutputArray _flow2)
89     {
90         UMat frame0 = arrGetUMat(_frame0, ubuf_[0]);
91         UMat frame1 = arrGetUMat(_frame1, ubuf_[1]);
92 
93         CV_Assert( frame1.type() == frame0.type() );
94         CV_Assert( frame1.size() == frame0.size() );
95 
96         UMat input0 = convertToType(frame0, work_type_, ubuf_[2], ubuf_[3]);
97         UMat input1 = convertToType(frame1, work_type_, ubuf_[4], ubuf_[5]);
98 
99         if (!_flow2.needed())
100         {
101             impl(input0, input1, _flow1);
102             return true;
103         }
104 
105         impl(input0, input1, uflow_);
106 
107         if (!_flow2.needed())
108             arrCopy(uflow_, _flow1);
109         else
110         {
111             split(uflow_, uflows_);
112 
113             arrCopy(uflows_[0], _flow1);
114             arrCopy(uflows_[1], _flow2);
115         }
116 
117         return true;
118     }
119 
calc(InputArray _frame0,InputArray _frame1,OutputArray _flow1,OutputArray _flow2)120     void CpuOpticalFlow::calc(InputArray _frame0, InputArray _frame1, OutputArray _flow1, OutputArray _flow2)
121     {
122         CV_OCL_RUN(_flow1.isUMat() && (_flow2.isUMat() || !_flow2.needed()),
123                    ocl_calc(_frame0, _frame1, _flow1, _flow2))
124 
125         Mat frame0 = arrGetMat(_frame0, buf_[0]);
126         Mat frame1 = arrGetMat(_frame1, buf_[1]);
127 
128         CV_Assert( frame1.type() == frame0.type() );
129         CV_Assert( frame1.size() == frame0.size() );
130 
131         Mat input0 = convertToType(frame0, work_type_, buf_[2], buf_[3]);
132         Mat input1 = convertToType(frame1, work_type_, buf_[4], buf_[5]);
133 
134         if (!_flow2.needed() && _flow1.kind() < _InputArray::OPENGL_BUFFER)
135         {
136             impl(input0, input1, _flow1);
137             return;
138         }
139 
140         impl(input0, input1, flow_);
141 
142         if (!_flow2.needed())
143             arrCopy(flow_, _flow1);
144         else
145         {
146             split(flow_, flows_);
147 
148             arrCopy(flows_[0], _flow1);
149             arrCopy(flows_[1], _flow2);
150         }
151     }
152 
collectGarbage()153     void CpuOpticalFlow::collectGarbage()
154     {
155         // Mat
156         for (int i = 0; i < 6; ++i)
157             buf_[i].release();
158         flow_.release();
159         flows_[0].release();
160         flows_[1].release();
161 
162         // UMat
163         for (int i = 0; i < 6; ++i)
164             ubuf_[i].release();
165         uflow_.release();
166         uflows_[0].release();
167         uflows_[1].release();
168     }
169 }
170 
171 ///////////////////////////////////////////////////////////////////
172 // Farneback
173 
174 namespace
175 {
176     class Farneback : public CpuOpticalFlow, public cv::superres::FarnebackOpticalFlow
177     {
178     public:
179         Farneback();
180         void calc(InputArray frame0, InputArray frame1, OutputArray flow1, OutputArray flow2);
181         void collectGarbage();
182 
183         CV_IMPL_PROPERTY(double, PyrScale, pyrScale_)
184         CV_IMPL_PROPERTY(int, LevelsNumber, numLevels_)
185         CV_IMPL_PROPERTY(int, WindowSize, winSize_)
186         CV_IMPL_PROPERTY(int, Iterations, numIters_)
187         CV_IMPL_PROPERTY(int, PolyN, polyN_)
188         CV_IMPL_PROPERTY(double, PolySigma, polySigma_)
189         CV_IMPL_PROPERTY(int, Flags, flags_)
190 
191     protected:
192         void impl(InputArray input0, InputArray input1, OutputArray dst);
193 
194     private:
195         double pyrScale_;
196         int numLevels_;
197         int winSize_;
198         int numIters_;
199         int polyN_;
200         double polySigma_;
201         int flags_;
202     };
203 
Farneback()204     Farneback::Farneback() : CpuOpticalFlow(CV_8UC1)
205     {
206         pyrScale_ = 0.5;
207         numLevels_ = 5;
208         winSize_ = 13;
209         numIters_ = 10;
210         polyN_ = 5;
211         polySigma_ = 1.1;
212         flags_ = 0;
213     }
214 
calc(InputArray frame0,InputArray frame1,OutputArray flow1,OutputArray flow2)215     void Farneback::calc(InputArray frame0, InputArray frame1, OutputArray flow1, OutputArray flow2)
216     {
217         CpuOpticalFlow::calc(frame0, frame1, flow1, flow2);
218     }
219 
collectGarbage()220     void Farneback::collectGarbage()
221     {
222         CpuOpticalFlow::collectGarbage();
223     }
224 
impl(InputArray input0,InputArray input1,OutputArray dst)225     void Farneback::impl(InputArray input0, InputArray input1, OutputArray dst)
226     {
227         calcOpticalFlowFarneback(input0, input1, InputOutputArray(dst), pyrScale_,
228                                  numLevels_, winSize_, numIters_,
229                                  polyN_, polySigma_, flags_);
230     }
231 }
232 
createOptFlow_Farneback()233 Ptr<cv::superres::FarnebackOpticalFlow> cv::superres::createOptFlow_Farneback()
234 {
235     return makePtr<Farneback>();
236 }
237 
238 ///////////////////////////////////////////////////////////////////
239 // Simple
240 
241 /*
242 namespace
243 {
244     class Simple : public CpuOpticalFlow
245     {
246     public:
247         AlgorithmInfo* info() const;
248 
249         Simple();
250 
251     protected:
252         void impl(InputArray input0, InputArray input1, OutputArray dst);
253 
254     private:
255         int layers_;
256         int averagingBlockSize_;
257         int maxFlow_;
258         double sigmaDist_;
259         double sigmaColor_;
260         int postProcessWindow_;
261         double sigmaDistFix_;
262         double sigmaColorFix_;
263         double occThr_;
264         int upscaleAveragingRadius_;
265         double upscaleSigmaDist_;
266         double upscaleSigmaColor_;
267         double speedUpThr_;
268     };
269 
270     CV_INIT_ALGORITHM(Simple, "DenseOpticalFlowExt.Simple",
271                       obj.info()->addParam(obj, "layers", obj.layers_);
272                       obj.info()->addParam(obj, "averagingBlockSize", obj.averagingBlockSize_);
273                       obj.info()->addParam(obj, "maxFlow", obj.maxFlow_);
274                       obj.info()->addParam(obj, "sigmaDist", obj.sigmaDist_);
275                       obj.info()->addParam(obj, "sigmaColor", obj.sigmaColor_);
276                       obj.info()->addParam(obj, "postProcessWindow", obj.postProcessWindow_);
277                       obj.info()->addParam(obj, "sigmaDistFix", obj.sigmaDistFix_);
278                       obj.info()->addParam(obj, "sigmaColorFix", obj.sigmaColorFix_);
279                       obj.info()->addParam(obj, "occThr", obj.occThr_);
280                       obj.info()->addParam(obj, "upscaleAveragingRadius", obj.upscaleAveragingRadius_);
281                       obj.info()->addParam(obj, "upscaleSigmaDist", obj.upscaleSigmaDist_);
282                       obj.info()->addParam(obj, "upscaleSigmaColor", obj.upscaleSigmaColor_);
283                       obj.info()->addParam(obj, "speedUpThr", obj.speedUpThr_))
284 
285     Simple::Simple() : CpuOpticalFlow(CV_8UC3)
286     {
287         layers_ = 3;
288         averagingBlockSize_ = 2;
289         maxFlow_ = 4;
290         sigmaDist_ = 4.1;
291         sigmaColor_ = 25.5;
292         postProcessWindow_ = 18;
293         sigmaDistFix_ = 55.0;
294         sigmaColorFix_ = 25.5;
295         occThr_ = 0.35;
296         upscaleAveragingRadius_ = 18;
297         upscaleSigmaDist_ = 55.0;
298         upscaleSigmaColor_ = 25.5;
299         speedUpThr_ = 10;
300     }
301 
302     void Simple::impl(InputArray _input0, InputArray _input1, OutputArray _dst)
303     {
304         calcOpticalFlowSF(_input0, _input1, _dst,
305                           layers_,
306                           averagingBlockSize_,
307                           maxFlow_,
308                           sigmaDist_,
309                           sigmaColor_,
310                           postProcessWindow_,
311                           sigmaDistFix_,
312                           sigmaColorFix_,
313                           occThr_,
314                           upscaleAveragingRadius_,
315                           upscaleSigmaDist_,
316                           upscaleSigmaColor_,
317                           speedUpThr_);
318     }
319 }
320 
321 Ptr<DenseOpticalFlowExt> cv::superres::createOptFlow_Simple()
322 {
323     return makePtr<Simple>();
324 }*/
325 
326 ///////////////////////////////////////////////////////////////////
327 // DualTVL1
328 
329 namespace
330 {
331     class DualTVL1 : public CpuOpticalFlow, public virtual cv::superres::DualTVL1OpticalFlow
332     {
333     public:
334         DualTVL1();
335         void calc(InputArray frame0, InputArray frame1, OutputArray flow1, OutputArray flow2);
336         void collectGarbage();
337 
338         CV_WRAP_SAME_PROPERTY(double, Tau, (*alg_))
339         CV_WRAP_SAME_PROPERTY(double, Lambda, (*alg_))
340         CV_WRAP_SAME_PROPERTY(double, Theta, (*alg_))
341         CV_WRAP_SAME_PROPERTY(int, ScalesNumber, (*alg_))
342         CV_WRAP_SAME_PROPERTY(int, WarpingsNumber, (*alg_))
343         CV_WRAP_SAME_PROPERTY(double, Epsilon, (*alg_))
344         CV_WRAP_PROPERTY(int, Iterations, OuterIterations, (*alg_))
345         CV_WRAP_SAME_PROPERTY(bool, UseInitialFlow, (*alg_))
346 
347     protected:
348         void impl(InputArray input0, InputArray input1, OutputArray dst);
349 
350     private:
351         Ptr<cv::DualTVL1OpticalFlow> alg_;
352     };
353 
DualTVL1()354     DualTVL1::DualTVL1() : CpuOpticalFlow(CV_8UC1)
355     {
356         alg_ = cv::createOptFlow_DualTVL1();
357     }
358 
calc(InputArray frame0,InputArray frame1,OutputArray flow1,OutputArray flow2)359     void DualTVL1::calc(InputArray frame0, InputArray frame1, OutputArray flow1, OutputArray flow2)
360     {
361         CpuOpticalFlow::calc(frame0, frame1, flow1, flow2);
362     }
363 
impl(InputArray input0,InputArray input1,OutputArray dst)364     void DualTVL1::impl(InputArray input0, InputArray input1, OutputArray dst)
365     {
366         alg_->calc(input0, input1, (InputOutputArray)dst);
367     }
368 
collectGarbage()369     void DualTVL1::collectGarbage()
370     {
371         alg_->collectGarbage();
372         CpuOpticalFlow::collectGarbage();
373     }
374 }
375 
createOptFlow_DualTVL1()376 Ptr<cv::superres::DualTVL1OpticalFlow> cv::superres::createOptFlow_DualTVL1()
377 {
378     return makePtr<DualTVL1>();
379 }
380 
381 ///////////////////////////////////////////////////////////////////
382 // GpuOpticalFlow
383 
384 #ifndef HAVE_OPENCV_CUDAOPTFLOW
385 
createOptFlow_Farneback_CUDA()386 Ptr<cv::superres::FarnebackOpticalFlow> cv::superres::createOptFlow_Farneback_CUDA()
387 {
388     CV_Error(cv::Error::StsNotImplemented, "The called functionality is disabled for current build or platform");
389     return Ptr<cv::superres::FarnebackOpticalFlow>();
390 }
391 
createOptFlow_DualTVL1_CUDA()392 Ptr<cv::superres::DualTVL1OpticalFlow> cv::superres::createOptFlow_DualTVL1_CUDA()
393 {
394     CV_Error(cv::Error::StsNotImplemented, "The called functionality is disabled for current build or platform");
395     return Ptr<cv::superres::DualTVL1OpticalFlow>();
396 }
397 
createOptFlow_Brox_CUDA()398 Ptr<cv::superres::BroxOpticalFlow> cv::superres::createOptFlow_Brox_CUDA()
399 {
400     CV_Error(cv::Error::StsNotImplemented, "The called functionality is disabled for current build or platform");
401     return Ptr<cv::superres::BroxOpticalFlow>();
402 }
403 
createOptFlow_PyrLK_CUDA()404 Ptr<cv::superres::PyrLKOpticalFlow> cv::superres::createOptFlow_PyrLK_CUDA()
405 {
406     CV_Error(cv::Error::StsNotImplemented, "The called functionality is disabled for current build or platform");
407     return Ptr<cv::superres::PyrLKOpticalFlow>();
408 }
409 
410 #else // HAVE_OPENCV_CUDAOPTFLOW
411 
412 namespace
413 {
414     class GpuOpticalFlow : public virtual cv::superres::DenseOpticalFlowExt
415     {
416     public:
417         explicit GpuOpticalFlow(int work_type);
418 
419         void calc(InputArray frame0, InputArray frame1, OutputArray flow1, OutputArray flow2);
420         void collectGarbage();
421 
422     protected:
423         virtual void impl(const GpuMat& input0, const GpuMat& input1, GpuMat& dst1, GpuMat& dst2) = 0;
424 
425     private:
426         int work_type_;
427         GpuMat buf_[6];
428         GpuMat u_, v_, flow_;
429     };
430 
GpuOpticalFlow(int work_type)431     GpuOpticalFlow::GpuOpticalFlow(int work_type) : work_type_(work_type)
432     {
433     }
434 
calc(InputArray _frame0,InputArray _frame1,OutputArray _flow1,OutputArray _flow2)435     void GpuOpticalFlow::calc(InputArray _frame0, InputArray _frame1, OutputArray _flow1, OutputArray _flow2)
436     {
437         GpuMat frame0 = arrGetGpuMat(_frame0, buf_[0]);
438         GpuMat frame1 = arrGetGpuMat(_frame1, buf_[1]);
439 
440         CV_Assert( frame1.type() == frame0.type() );
441         CV_Assert( frame1.size() == frame0.size() );
442 
443         GpuMat input0 = convertToType(frame0, work_type_, buf_[2], buf_[3]);
444         GpuMat input1 = convertToType(frame1, work_type_, buf_[4], buf_[5]);
445 
446         if (_flow2.needed() && _flow1.kind() == _InputArray::CUDA_GPU_MAT && _flow2.kind() == _InputArray::CUDA_GPU_MAT)
447         {
448             impl(input0, input1, _flow1.getGpuMatRef(), _flow2.getGpuMatRef());
449             return;
450         }
451 
452         impl(input0, input1, u_, v_);
453 
454         if (_flow2.needed())
455         {
456             arrCopy(u_, _flow1);
457             arrCopy(v_, _flow2);
458         }
459         else
460         {
461             GpuMat src[] = {u_, v_};
462             merge(src, 2, flow_);
463             arrCopy(flow_, _flow1);
464         }
465     }
466 
collectGarbage()467     void GpuOpticalFlow::collectGarbage()
468     {
469         for (int i = 0; i < 6; ++i)
470             buf_[i].release();
471         u_.release();
472         v_.release();
473         flow_.release();
474     }
475 }
476 
477 ///////////////////////////////////////////////////////////////////
478 // Brox_CUDA
479 
480 namespace
481 {
482     class Brox_CUDA : public GpuOpticalFlow, public virtual cv::superres::BroxOpticalFlow
483     {
484     public:
485         Brox_CUDA();
486         void calc(InputArray frame0, InputArray frame1, OutputArray flow1, OutputArray flow2);
487         void collectGarbage();
488 
489         CV_IMPL_PROPERTY(double, Alpha, alpha_)
490         CV_IMPL_PROPERTY(double, Gamma, gamma_)
491         CV_IMPL_PROPERTY(double, ScaleFactor, scaleFactor_)
492         CV_IMPL_PROPERTY(int, InnerIterations, innerIterations_)
493         CV_IMPL_PROPERTY(int, OuterIterations, outerIterations_)
494         CV_IMPL_PROPERTY(int, SolverIterations, solverIterations_)
495 
496     protected:
497         void impl(const GpuMat& input0, const GpuMat& input1, GpuMat& dst1, GpuMat& dst2);
498 
499     private:
500         double alpha_;
501         double gamma_;
502         double scaleFactor_;
503         int innerIterations_;
504         int outerIterations_;
505         int solverIterations_;
506 
507         Ptr<cuda::BroxOpticalFlow> alg_;
508     };
509 
Brox_CUDA()510     Brox_CUDA::Brox_CUDA() : GpuOpticalFlow(CV_32FC1)
511     {
512         alg_ = cuda::BroxOpticalFlow::create(0.197f, 50.0f, 0.8f, 10, 77, 10);
513 
514         alpha_ = alg_->getFlowSmoothness();
515         gamma_ = alg_->getGradientConstancyImportance();
516         scaleFactor_ = alg_->getPyramidScaleFactor();
517         innerIterations_ = alg_->getInnerIterations();
518         outerIterations_ = alg_->getOuterIterations();
519         solverIterations_ = alg_->getSolverIterations();
520     }
521 
calc(InputArray frame0,InputArray frame1,OutputArray flow1,OutputArray flow2)522     void Brox_CUDA::calc(InputArray frame0, InputArray frame1, OutputArray flow1, OutputArray flow2)
523     {
524         GpuOpticalFlow::calc(frame0, frame1, flow1, flow2);
525     }
526 
impl(const GpuMat & input0,const GpuMat & input1,GpuMat & dst1,GpuMat & dst2)527     void Brox_CUDA::impl(const GpuMat& input0, const GpuMat& input1, GpuMat& dst1, GpuMat& dst2)
528     {
529         alg_->setFlowSmoothness(alpha_);
530         alg_->setGradientConstancyImportance(gamma_);
531         alg_->setPyramidScaleFactor(scaleFactor_);
532         alg_->setInnerIterations(innerIterations_);
533         alg_->setOuterIterations(outerIterations_);
534         alg_->setSolverIterations(solverIterations_);
535 
536         GpuMat flow;
537         alg_->calc(input0, input1, flow);
538 
539         GpuMat flows[2];
540         cuda::split(flow, flows);
541 
542         dst1 = flows[0];
543         dst2 = flows[1];
544     }
545 
collectGarbage()546     void Brox_CUDA::collectGarbage()
547     {
548         alg_ = cuda::BroxOpticalFlow::create(alpha_, gamma_, scaleFactor_, innerIterations_, outerIterations_, solverIterations_);
549         GpuOpticalFlow::collectGarbage();
550     }
551 }
552 
createOptFlow_Brox_CUDA()553 Ptr<cv::superres::BroxOpticalFlow> cv::superres::createOptFlow_Brox_CUDA()
554 {
555     return makePtr<Brox_CUDA>();
556 }
557 
558 ///////////////////////////////////////////////////////////////////
559 // PyrLK_CUDA
560 
561 namespace
562 {
563     class PyrLK_CUDA : public GpuOpticalFlow, public cv::superres::PyrLKOpticalFlow
564     {
565     public:
566         PyrLK_CUDA();
567         void calc(InputArray frame0, InputArray frame1, OutputArray flow1, OutputArray flow2);
568         void collectGarbage();
569 
570         CV_IMPL_PROPERTY(int, WindowSize, winSize_)
571         CV_IMPL_PROPERTY(int, MaxLevel, maxLevel_)
572         CV_IMPL_PROPERTY(int, Iterations, iterations_)
573 
574     protected:
575         void impl(const GpuMat& input0, const GpuMat& input1, GpuMat& dst1, GpuMat& dst2);
576 
577     private:
578         int winSize_;
579         int maxLevel_;
580         int iterations_;
581 
582         Ptr<cuda::DensePyrLKOpticalFlow> alg_;
583     };
584 
PyrLK_CUDA()585     PyrLK_CUDA::PyrLK_CUDA() : GpuOpticalFlow(CV_8UC1)
586     {
587         alg_ = cuda::DensePyrLKOpticalFlow::create();
588 
589         winSize_ = alg_->getWinSize().width;
590         maxLevel_ = alg_->getMaxLevel();
591         iterations_ = alg_->getNumIters();
592     }
593 
calc(InputArray frame0,InputArray frame1,OutputArray flow1,OutputArray flow2)594     void PyrLK_CUDA::calc(InputArray frame0, InputArray frame1, OutputArray flow1, OutputArray flow2)
595     {
596         GpuOpticalFlow::calc(frame0, frame1, flow1, flow2);
597     }
598 
impl(const GpuMat & input0,const GpuMat & input1,GpuMat & dst1,GpuMat & dst2)599     void PyrLK_CUDA::impl(const GpuMat& input0, const GpuMat& input1, GpuMat& dst1, GpuMat& dst2)
600     {
601         alg_->setWinSize(Size(winSize_, winSize_));
602         alg_->setMaxLevel(maxLevel_);
603         alg_->setNumIters(iterations_);
604 
605         GpuMat flow;
606         alg_->calc(input0, input1, flow);
607 
608         GpuMat flows[2];
609         cuda::split(flow, flows);
610 
611         dst1 = flows[0];
612         dst2 = flows[1];
613     }
614 
collectGarbage()615     void PyrLK_CUDA::collectGarbage()
616     {
617         alg_ = cuda::DensePyrLKOpticalFlow::create();
618         GpuOpticalFlow::collectGarbage();
619     }
620 }
621 
createOptFlow_PyrLK_CUDA()622 Ptr<cv::superres::PyrLKOpticalFlow> cv::superres::createOptFlow_PyrLK_CUDA()
623 {
624     return makePtr<PyrLK_CUDA>();
625 }
626 
627 ///////////////////////////////////////////////////////////////////
628 // Farneback_CUDA
629 
630 namespace
631 {
632     class Farneback_CUDA : public GpuOpticalFlow, public cv::superres::FarnebackOpticalFlow
633     {
634     public:
635         Farneback_CUDA();
636         void calc(InputArray frame0, InputArray frame1, OutputArray flow1, OutputArray flow2);
637         void collectGarbage();
638 
639         CV_IMPL_PROPERTY(double, PyrScale, pyrScale_)
640         CV_IMPL_PROPERTY(int, LevelsNumber, numLevels_)
641         CV_IMPL_PROPERTY(int, WindowSize, winSize_)
642         CV_IMPL_PROPERTY(int, Iterations, numIters_)
643         CV_IMPL_PROPERTY(int, PolyN, polyN_)
644         CV_IMPL_PROPERTY(double, PolySigma, polySigma_)
645         CV_IMPL_PROPERTY(int, Flags, flags_)
646 
647     protected:
648         void impl(const GpuMat& input0, const GpuMat& input1, GpuMat& dst1, GpuMat& dst2);
649 
650     private:
651         double pyrScale_;
652         int numLevels_;
653         int winSize_;
654         int numIters_;
655         int polyN_;
656         double polySigma_;
657         int flags_;
658 
659         Ptr<cuda::FarnebackOpticalFlow> alg_;
660     };
661 
Farneback_CUDA()662     Farneback_CUDA::Farneback_CUDA() : GpuOpticalFlow(CV_8UC1)
663     {
664         alg_ = cuda::FarnebackOpticalFlow::create();
665 
666         pyrScale_ = alg_->getPyrScale();
667         numLevels_ = alg_->getNumLevels();
668         winSize_ = alg_->getWinSize();
669         numIters_ = alg_->getNumIters();
670         polyN_ = alg_->getPolyN();
671         polySigma_ = alg_->getPolySigma();
672         flags_ = alg_->getFlags();
673     }
674 
calc(InputArray frame0,InputArray frame1,OutputArray flow1,OutputArray flow2)675     void Farneback_CUDA::calc(InputArray frame0, InputArray frame1, OutputArray flow1, OutputArray flow2)
676     {
677         GpuOpticalFlow::calc(frame0, frame1, flow1, flow2);
678     }
679 
impl(const GpuMat & input0,const GpuMat & input1,GpuMat & dst1,GpuMat & dst2)680     void Farneback_CUDA::impl(const GpuMat& input0, const GpuMat& input1, GpuMat& dst1, GpuMat& dst2)
681     {
682         alg_->setPyrScale(pyrScale_);
683         alg_->setNumLevels(numLevels_);
684         alg_->setWinSize(winSize_);
685         alg_->setNumIters(numIters_);
686         alg_->setPolyN(polyN_);
687         alg_->setPolySigma(polySigma_);
688         alg_->setFlags(flags_);
689 
690         GpuMat flow;
691         alg_->calc(input0, input1, flow);
692 
693         GpuMat flows[2];
694         cuda::split(flow, flows);
695 
696         dst1 = flows[0];
697         dst2 = flows[1];
698     }
699 
collectGarbage()700     void Farneback_CUDA::collectGarbage()
701     {
702         alg_ = cuda::FarnebackOpticalFlow::create();
703         GpuOpticalFlow::collectGarbage();
704     }
705 }
706 
createOptFlow_Farneback_CUDA()707 Ptr<cv::superres::FarnebackOpticalFlow> cv::superres::createOptFlow_Farneback_CUDA()
708 {
709     return makePtr<Farneback_CUDA>();
710 }
711 
712 ///////////////////////////////////////////////////////////////////
713 // DualTVL1_CUDA
714 
715 namespace
716 {
717     class DualTVL1_CUDA : public GpuOpticalFlow, public cv::superres::DualTVL1OpticalFlow
718     {
719     public:
720         DualTVL1_CUDA();
721         void calc(InputArray frame0, InputArray frame1, OutputArray flow1, OutputArray flow2);
722         void collectGarbage();
723 
724         CV_IMPL_PROPERTY(double, Tau, tau_)
725         CV_IMPL_PROPERTY(double, Lambda, lambda_)
726         CV_IMPL_PROPERTY(double, Theta, theta_)
727         CV_IMPL_PROPERTY(int, ScalesNumber, nscales_)
728         CV_IMPL_PROPERTY(int, WarpingsNumber, warps_)
729         CV_IMPL_PROPERTY(double, Epsilon, epsilon_)
730         CV_IMPL_PROPERTY(int, Iterations, iterations_)
731         CV_IMPL_PROPERTY(bool, UseInitialFlow, useInitialFlow_)
732 
733     protected:
734         void impl(const GpuMat& input0, const GpuMat& input1, GpuMat& dst1, GpuMat& dst2);
735 
736     private:
737         double tau_;
738         double lambda_;
739         double theta_;
740         int nscales_;
741         int warps_;
742         double epsilon_;
743         int iterations_;
744         bool useInitialFlow_;
745 
746         Ptr<cuda::OpticalFlowDual_TVL1> alg_;
747     };
748 
DualTVL1_CUDA()749     DualTVL1_CUDA::DualTVL1_CUDA() : GpuOpticalFlow(CV_8UC1)
750     {
751         alg_ = cuda::OpticalFlowDual_TVL1::create();
752 
753         tau_ = alg_->getTau();
754         lambda_ = alg_->getLambda();
755         theta_ = alg_->getTheta();
756         nscales_ = alg_->getNumScales();
757         warps_ = alg_->getNumWarps();
758         epsilon_ = alg_->getEpsilon();
759         iterations_ = alg_->getNumIterations();
760         useInitialFlow_ = alg_->getUseInitialFlow();
761     }
762 
calc(InputArray frame0,InputArray frame1,OutputArray flow1,OutputArray flow2)763     void DualTVL1_CUDA::calc(InputArray frame0, InputArray frame1, OutputArray flow1, OutputArray flow2)
764     {
765         GpuOpticalFlow::calc(frame0, frame1, flow1, flow2);
766     }
767 
impl(const GpuMat & input0,const GpuMat & input1,GpuMat & dst1,GpuMat & dst2)768     void DualTVL1_CUDA::impl(const GpuMat& input0, const GpuMat& input1, GpuMat& dst1, GpuMat& dst2)
769     {
770         alg_->setTau(tau_);
771         alg_->setLambda(lambda_);
772         alg_->setTheta(theta_);
773         alg_->setNumScales(nscales_);
774         alg_->setNumWarps(warps_);
775         alg_->setEpsilon(epsilon_);
776         alg_->setNumIterations(iterations_);
777         alg_->setUseInitialFlow(useInitialFlow_);
778 
779         GpuMat flow;
780         alg_->calc(input0, input1, flow);
781 
782         GpuMat flows[2];
783         cuda::split(flow, flows);
784 
785         dst1 = flows[0];
786         dst2 = flows[1];
787     }
788 
collectGarbage()789     void DualTVL1_CUDA::collectGarbage()
790     {
791         alg_ = cuda::OpticalFlowDual_TVL1::create();
792         GpuOpticalFlow::collectGarbage();
793     }
794 }
795 
createOptFlow_DualTVL1_CUDA()796 Ptr<cv::superres::DualTVL1OpticalFlow> cv::superres::createOptFlow_DualTVL1_CUDA()
797 {
798     return makePtr<DualTVL1_CUDA>();
799 }
800 
801 #endif // HAVE_OPENCV_CUDAOPTFLOW
802