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