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