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 // S. Farsiu , D. Robinson, M. Elad, P. Milanfar. Fast and robust multiframe super resolution.
44 // Dennis Mitzel, Thomas Pock, Thomas Schoenemann, Daniel Cremers. Video Super Resolution using Duality Based TV-L1 Optical Flow.
45
46 #include "precomp.hpp"
47
48 using namespace cv;
49 using namespace cv::cuda;
50 using namespace cv::superres;
51 using namespace cv::superres::detail;
52
53 #if !defined(HAVE_CUDA) || !defined(HAVE_OPENCV_CUDAARITHM) || !defined(HAVE_OPENCV_CUDAWARPING) || !defined(HAVE_OPENCV_CUDAFILTERS)
54
createSuperResolution_BTVL1_CUDA()55 Ptr<SuperResolution> cv::superres::createSuperResolution_BTVL1_CUDA()
56 {
57 CV_Error(Error::StsNotImplemented, "The called functionality is disabled for current build or platform");
58 return Ptr<SuperResolution>();
59 }
60
61 #else // HAVE_CUDA
62
63 namespace btv_l1_cudev
64 {
65 void buildMotionMaps(PtrStepSzf forwardMotionX, PtrStepSzf forwardMotionY,
66 PtrStepSzf backwardMotionX, PtrStepSzf bacwardMotionY,
67 PtrStepSzf forwardMapX, PtrStepSzf forwardMapY,
68 PtrStepSzf backwardMapX, PtrStepSzf backwardMapY);
69
70 template <int cn>
71 void upscale(const PtrStepSzb src, PtrStepSzb dst, int scale, cudaStream_t stream);
72
73 void diffSign(PtrStepSzf src1, PtrStepSzf src2, PtrStepSzf dst, cudaStream_t stream);
74
75 void loadBtvWeights(const float* weights, size_t count);
76 template <int cn> void calcBtvRegularization(PtrStepSzb src, PtrStepSzb dst, int ksize);
77 }
78
79 namespace
80 {
calcRelativeMotions(const std::vector<std::pair<GpuMat,GpuMat>> & forwardMotions,const std::vector<std::pair<GpuMat,GpuMat>> & backwardMotions,std::vector<std::pair<GpuMat,GpuMat>> & relForwardMotions,std::vector<std::pair<GpuMat,GpuMat>> & relBackwardMotions,int baseIdx,Size size)81 void calcRelativeMotions(const std::vector<std::pair<GpuMat, GpuMat> >& forwardMotions, const std::vector<std::pair<GpuMat, GpuMat> >& backwardMotions,
82 std::vector<std::pair<GpuMat, GpuMat> >& relForwardMotions, std::vector<std::pair<GpuMat, GpuMat> >& relBackwardMotions,
83 int baseIdx, Size size)
84 {
85 const int count = static_cast<int>(forwardMotions.size());
86
87 relForwardMotions.resize(count);
88 relForwardMotions[baseIdx].first.create(size, CV_32FC1);
89 relForwardMotions[baseIdx].first.setTo(Scalar::all(0));
90 relForwardMotions[baseIdx].second.create(size, CV_32FC1);
91 relForwardMotions[baseIdx].second.setTo(Scalar::all(0));
92
93 relBackwardMotions.resize(count);
94 relBackwardMotions[baseIdx].first.create(size, CV_32FC1);
95 relBackwardMotions[baseIdx].first.setTo(Scalar::all(0));
96 relBackwardMotions[baseIdx].second.create(size, CV_32FC1);
97 relBackwardMotions[baseIdx].second.setTo(Scalar::all(0));
98
99 for (int i = baseIdx - 1; i >= 0; --i)
100 {
101 cuda::add(relForwardMotions[i + 1].first, forwardMotions[i].first, relForwardMotions[i].first);
102 cuda::add(relForwardMotions[i + 1].second, forwardMotions[i].second, relForwardMotions[i].second);
103
104 cuda::add(relBackwardMotions[i + 1].first, backwardMotions[i + 1].first, relBackwardMotions[i].first);
105 cuda::add(relBackwardMotions[i + 1].second, backwardMotions[i + 1].second, relBackwardMotions[i].second);
106 }
107
108 for (int i = baseIdx + 1; i < count; ++i)
109 {
110 cuda::add(relForwardMotions[i - 1].first, backwardMotions[i].first, relForwardMotions[i].first);
111 cuda::add(relForwardMotions[i - 1].second, backwardMotions[i].second, relForwardMotions[i].second);
112
113 cuda::add(relBackwardMotions[i - 1].first, forwardMotions[i - 1].first, relBackwardMotions[i].first);
114 cuda::add(relBackwardMotions[i - 1].second, forwardMotions[i - 1].second, relBackwardMotions[i].second);
115 }
116 }
117
upscaleMotions(const std::vector<std::pair<GpuMat,GpuMat>> & lowResMotions,std::vector<std::pair<GpuMat,GpuMat>> & highResMotions,int scale)118 void upscaleMotions(const std::vector<std::pair<GpuMat, GpuMat> >& lowResMotions, std::vector<std::pair<GpuMat, GpuMat> >& highResMotions, int scale)
119 {
120 highResMotions.resize(lowResMotions.size());
121
122 for (size_t i = 0; i < lowResMotions.size(); ++i)
123 {
124 cuda::resize(lowResMotions[i].first, highResMotions[i].first, Size(), scale, scale, INTER_CUBIC);
125 cuda::resize(lowResMotions[i].second, highResMotions[i].second, Size(), scale, scale, INTER_CUBIC);
126
127 cuda::multiply(highResMotions[i].first, Scalar::all(scale), highResMotions[i].first);
128 cuda::multiply(highResMotions[i].second, Scalar::all(scale), highResMotions[i].second);
129 }
130 }
131
buildMotionMaps(const std::pair<GpuMat,GpuMat> & forwardMotion,const std::pair<GpuMat,GpuMat> & backwardMotion,std::pair<GpuMat,GpuMat> & forwardMap,std::pair<GpuMat,GpuMat> & backwardMap)132 void buildMotionMaps(const std::pair<GpuMat, GpuMat>& forwardMotion, const std::pair<GpuMat, GpuMat>& backwardMotion,
133 std::pair<GpuMat, GpuMat>& forwardMap, std::pair<GpuMat, GpuMat>& backwardMap)
134 {
135 forwardMap.first.create(forwardMotion.first.size(), CV_32FC1);
136 forwardMap.second.create(forwardMotion.first.size(), CV_32FC1);
137
138 backwardMap.first.create(forwardMotion.first.size(), CV_32FC1);
139 backwardMap.second.create(forwardMotion.first.size(), CV_32FC1);
140
141 btv_l1_cudev::buildMotionMaps(forwardMotion.first, forwardMotion.second,
142 backwardMotion.first, backwardMotion.second,
143 forwardMap.first, forwardMap.second,
144 backwardMap.first, backwardMap.second);
145 }
146
upscale(const GpuMat & src,GpuMat & dst,int scale,Stream & stream)147 void upscale(const GpuMat& src, GpuMat& dst, int scale, Stream& stream)
148 {
149 typedef void (*func_t)(const PtrStepSzb src, PtrStepSzb dst, int scale, cudaStream_t stream);
150 static const func_t funcs[] =
151 {
152 0, btv_l1_cudev::upscale<1>, 0, btv_l1_cudev::upscale<3>, btv_l1_cudev::upscale<4>
153 };
154
155 CV_Assert( src.channels() == 1 || src.channels() == 3 || src.channels() == 4 );
156
157 dst.create(src.rows * scale, src.cols * scale, src.type());
158 dst.setTo(Scalar::all(0));
159
160 const func_t func = funcs[src.channels()];
161
162 func(src, dst, scale, StreamAccessor::getStream(stream));
163 }
164
diffSign(const GpuMat & src1,const GpuMat & src2,GpuMat & dst,Stream & stream)165 void diffSign(const GpuMat& src1, const GpuMat& src2, GpuMat& dst, Stream& stream)
166 {
167 dst.create(src1.size(), src1.type());
168
169 btv_l1_cudev::diffSign(src1.reshape(1), src2.reshape(1), dst.reshape(1), StreamAccessor::getStream(stream));
170 }
171
calcBtvWeights(int btvKernelSize,double alpha,std::vector<float> & btvWeights)172 void calcBtvWeights(int btvKernelSize, double alpha, std::vector<float>& btvWeights)
173 {
174 const size_t size = btvKernelSize * btvKernelSize;
175
176 btvWeights.resize(size);
177
178 const int ksize = (btvKernelSize - 1) / 2;
179 const float alpha_f = static_cast<float>(alpha);
180
181 for (int m = 0, ind = 0; m <= ksize; ++m)
182 {
183 for (int l = ksize; l + m >= 0; --l, ++ind)
184 btvWeights[ind] = pow(alpha_f, std::abs(m) + std::abs(l));
185 }
186
187 btv_l1_cudev::loadBtvWeights(&btvWeights[0], size);
188 }
189
calcBtvRegularization(const GpuMat & src,GpuMat & dst,int btvKernelSize)190 void calcBtvRegularization(const GpuMat& src, GpuMat& dst, int btvKernelSize)
191 {
192 typedef void (*func_t)(PtrStepSzb src, PtrStepSzb dst, int ksize);
193 static const func_t funcs[] =
194 {
195 0,
196 btv_l1_cudev::calcBtvRegularization<1>,
197 0,
198 btv_l1_cudev::calcBtvRegularization<3>,
199 btv_l1_cudev::calcBtvRegularization<4>
200 };
201
202 dst.create(src.size(), src.type());
203 dst.setTo(Scalar::all(0));
204
205 const int ksize = (btvKernelSize - 1) / 2;
206
207 funcs[src.channels()](src, dst, ksize);
208 }
209
210 class BTVL1_CUDA_Base : public cv::superres::SuperResolution
211 {
212 public:
213 BTVL1_CUDA_Base();
214
215 void process(const std::vector<GpuMat>& src, GpuMat& dst,
216 const std::vector<std::pair<GpuMat, GpuMat> >& forwardMotions, const std::vector<std::pair<GpuMat, GpuMat> >& backwardMotions,
217 int baseIdx);
218
219 void collectGarbage();
220
221 CV_IMPL_PROPERTY(int, Scale, scale_)
222 CV_IMPL_PROPERTY(int, Iterations, iterations_)
223 CV_IMPL_PROPERTY(double, Tau, tau_)
224 CV_IMPL_PROPERTY(double, Labmda, lambda_)
225 CV_IMPL_PROPERTY(double, Alpha, alpha_)
226 CV_IMPL_PROPERTY(int, KernelSize, btvKernelSize_)
227 CV_IMPL_PROPERTY(int, BlurKernelSize, blurKernelSize_)
228 CV_IMPL_PROPERTY(double, BlurSigma, blurSigma_)
229 CV_IMPL_PROPERTY(int, TemporalAreaRadius, temporalAreaRadius_)
230 CV_IMPL_PROPERTY_S(Ptr<cv::superres::DenseOpticalFlowExt>, OpticalFlow, opticalFlow_)
231
232 protected:
233 int scale_;
234 int iterations_;
235 double lambda_;
236 double tau_;
237 double alpha_;
238 int btvKernelSize_;
239 int blurKernelSize_;
240 double blurSigma_;
241 int temporalAreaRadius_;
242 Ptr<cv::superres::DenseOpticalFlowExt> opticalFlow_;
243
244 private:
245 std::vector<Ptr<cuda::Filter> > filters_;
246 int curBlurKernelSize_;
247 double curBlurSigma_;
248 int curSrcType_;
249
250 std::vector<float> btvWeights_;
251 int curBtvKernelSize_;
252 double curAlpha_;
253
254 std::vector<std::pair<GpuMat, GpuMat> > lowResForwardMotions_;
255 std::vector<std::pair<GpuMat, GpuMat> > lowResBackwardMotions_;
256
257 std::vector<std::pair<GpuMat, GpuMat> > highResForwardMotions_;
258 std::vector<std::pair<GpuMat, GpuMat> > highResBackwardMotions_;
259
260 std::vector<std::pair<GpuMat, GpuMat> > forwardMaps_;
261 std::vector<std::pair<GpuMat, GpuMat> > backwardMaps_;
262
263 GpuMat highRes_;
264
265 std::vector<Stream> streams_;
266 std::vector<GpuMat> diffTerms_;
267 std::vector<GpuMat> a_, b_, c_;
268 GpuMat regTerm_;
269 };
270
BTVL1_CUDA_Base()271 BTVL1_CUDA_Base::BTVL1_CUDA_Base()
272 {
273 scale_ = 4;
274 iterations_ = 180;
275 lambda_ = 0.03;
276 tau_ = 1.3;
277 alpha_ = 0.7;
278 btvKernelSize_ = 7;
279 blurKernelSize_ = 5;
280 blurSigma_ = 0.0;
281
282 #ifdef HAVE_OPENCV_CUDAOPTFLOW
283 opticalFlow_ = createOptFlow_Farneback_CUDA();
284 #else
285 opticalFlow_ = createOptFlow_Farneback();
286 #endif
287 temporalAreaRadius_ = 0;
288
289 curBlurKernelSize_ = -1;
290 curBlurSigma_ = -1.0;
291 curSrcType_ = -1;
292
293 curBtvKernelSize_ = -1;
294 curAlpha_ = -1.0;
295 }
296
process(const std::vector<GpuMat> & src,GpuMat & dst,const std::vector<std::pair<GpuMat,GpuMat>> & forwardMotions,const std::vector<std::pair<GpuMat,GpuMat>> & backwardMotions,int baseIdx)297 void BTVL1_CUDA_Base::process(const std::vector<GpuMat>& src, GpuMat& dst,
298 const std::vector<std::pair<GpuMat, GpuMat> >& forwardMotions, const std::vector<std::pair<GpuMat, GpuMat> >& backwardMotions,
299 int baseIdx)
300 {
301 CV_Assert( scale_ > 1 );
302 CV_Assert( iterations_ > 0 );
303 CV_Assert( tau_ > 0.0 );
304 CV_Assert( alpha_ > 0.0 );
305 CV_Assert( btvKernelSize_ > 0 && btvKernelSize_ <= 16 );
306 CV_Assert( blurKernelSize_ > 0 );
307 CV_Assert( blurSigma_ >= 0.0 );
308
309 // update blur filter and btv weights
310
311 if (filters_.size() != src.size() || blurKernelSize_ != curBlurKernelSize_ || blurSigma_ != curBlurSigma_ || src[0].type() != curSrcType_)
312 {
313 filters_.resize(src.size());
314 for (size_t i = 0; i < src.size(); ++i)
315 filters_[i] = cuda::createGaussianFilter(src[0].type(), -1, Size(blurKernelSize_, blurKernelSize_), blurSigma_);
316 curBlurKernelSize_ = blurKernelSize_;
317 curBlurSigma_ = blurSigma_;
318 curSrcType_ = src[0].type();
319 }
320
321 if (btvWeights_.empty() || btvKernelSize_ != curBtvKernelSize_ || alpha_ != curAlpha_)
322 {
323 calcBtvWeights(btvKernelSize_, alpha_, btvWeights_);
324 curBtvKernelSize_ = btvKernelSize_;
325 curAlpha_ = alpha_;
326 }
327
328 // calc motions between input frames
329
330 calcRelativeMotions(forwardMotions, backwardMotions, lowResForwardMotions_, lowResBackwardMotions_, baseIdx, src[0].size());
331
332 upscaleMotions(lowResForwardMotions_, highResForwardMotions_, scale_);
333 upscaleMotions(lowResBackwardMotions_, highResBackwardMotions_, scale_);
334
335 forwardMaps_.resize(highResForwardMotions_.size());
336 backwardMaps_.resize(highResForwardMotions_.size());
337 for (size_t i = 0; i < highResForwardMotions_.size(); ++i)
338 buildMotionMaps(highResForwardMotions_[i], highResBackwardMotions_[i], forwardMaps_[i], backwardMaps_[i]);
339
340 // initial estimation
341
342 const Size lowResSize = src[0].size();
343 const Size highResSize(lowResSize.width * scale_, lowResSize.height * scale_);
344
345 cuda::resize(src[baseIdx], highRes_, highResSize, 0, 0, INTER_CUBIC);
346
347 // iterations
348
349 streams_.resize(src.size());
350 diffTerms_.resize(src.size());
351 a_.resize(src.size());
352 b_.resize(src.size());
353 c_.resize(src.size());
354
355 for (int i = 0; i < iterations_; ++i)
356 {
357 for (size_t k = 0; k < src.size(); ++k)
358 {
359 // a = M * Ih
360 cuda::remap(highRes_, a_[k], backwardMaps_[k].first, backwardMaps_[k].second, INTER_NEAREST, BORDER_REPLICATE, Scalar(), streams_[k]);
361 // b = HM * Ih
362 filters_[k]->apply(a_[k], b_[k], streams_[k]);
363 // c = DHF * Ih
364 cuda::resize(b_[k], c_[k], lowResSize, 0, 0, INTER_NEAREST, streams_[k]);
365
366 diffSign(src[k], c_[k], c_[k], streams_[k]);
367
368 // a = Dt * diff
369 upscale(c_[k], a_[k], scale_, streams_[k]);
370 // b = HtDt * diff
371 filters_[k]->apply(a_[k], b_[k], streams_[k]);
372 // diffTerm = MtHtDt * diff
373 cuda::remap(b_[k], diffTerms_[k], forwardMaps_[k].first, forwardMaps_[k].second, INTER_NEAREST, BORDER_REPLICATE, Scalar(), streams_[k]);
374 }
375
376 if (lambda_ > 0)
377 {
378 calcBtvRegularization(highRes_, regTerm_, btvKernelSize_);
379 cuda::addWeighted(highRes_, 1.0, regTerm_, -tau_ * lambda_, 0.0, highRes_);
380 }
381
382 for (size_t k = 0; k < src.size(); ++k)
383 {
384 streams_[k].waitForCompletion();
385 cuda::addWeighted(highRes_, 1.0, diffTerms_[k], tau_, 0.0, highRes_);
386 }
387 }
388
389 Rect inner(btvKernelSize_, btvKernelSize_, highRes_.cols - 2 * btvKernelSize_, highRes_.rows - 2 * btvKernelSize_);
390 highRes_(inner).copyTo(dst);
391 }
392
collectGarbage()393 void BTVL1_CUDA_Base::collectGarbage()
394 {
395 filters_.clear();
396
397 lowResForwardMotions_.clear();
398 lowResBackwardMotions_.clear();
399
400 highResForwardMotions_.clear();
401 highResBackwardMotions_.clear();
402
403 forwardMaps_.clear();
404 backwardMaps_.clear();
405
406 highRes_.release();
407
408 diffTerms_.clear();
409 a_.clear();
410 b_.clear();
411 c_.clear();
412 regTerm_.release();
413 }
414
415 ////////////////////////////////////////////////////////////
416
417 class BTVL1_CUDA : public BTVL1_CUDA_Base
418 {
419 public:
420 BTVL1_CUDA();
421
422 void collectGarbage();
423
424 protected:
425 void initImpl(Ptr<FrameSource>& frameSource);
426 void processImpl(Ptr<FrameSource>& frameSource, OutputArray output);
427
428 private:
429 void readNextFrame(Ptr<FrameSource>& frameSource);
430 void processFrame(int idx);
431
432 GpuMat curFrame_;
433 GpuMat prevFrame_;
434
435 std::vector<GpuMat> frames_;
436 std::vector<std::pair<GpuMat, GpuMat> > forwardMotions_;
437 std::vector<std::pair<GpuMat, GpuMat> > backwardMotions_;
438 std::vector<GpuMat> outputs_;
439
440 int storePos_;
441 int procPos_;
442 int outPos_;
443
444 std::vector<GpuMat> srcFrames_;
445 std::vector<std::pair<GpuMat, GpuMat> > srcForwardMotions_;
446 std::vector<std::pair<GpuMat, GpuMat> > srcBackwardMotions_;
447 GpuMat finalOutput_;
448 };
449
BTVL1_CUDA()450 BTVL1_CUDA::BTVL1_CUDA()
451 {
452 temporalAreaRadius_ = 4;
453 }
454
collectGarbage()455 void BTVL1_CUDA::collectGarbage()
456 {
457 curFrame_.release();
458 prevFrame_.release();
459
460 frames_.clear();
461 forwardMotions_.clear();
462 backwardMotions_.clear();
463 outputs_.clear();
464
465 srcFrames_.clear();
466 srcForwardMotions_.clear();
467 srcBackwardMotions_.clear();
468 finalOutput_.release();
469
470 SuperResolution::collectGarbage();
471 BTVL1_CUDA_Base::collectGarbage();
472 }
473
initImpl(Ptr<FrameSource> & frameSource)474 void BTVL1_CUDA::initImpl(Ptr<FrameSource>& frameSource)
475 {
476 const int cacheSize = 2 * temporalAreaRadius_ + 1;
477
478 frames_.resize(cacheSize);
479 forwardMotions_.resize(cacheSize);
480 backwardMotions_.resize(cacheSize);
481 outputs_.resize(cacheSize);
482
483 storePos_ = -1;
484
485 for (int t = -temporalAreaRadius_; t <= temporalAreaRadius_; ++t)
486 readNextFrame(frameSource);
487
488 for (int i = 0; i <= temporalAreaRadius_; ++i)
489 processFrame(i);
490
491 procPos_ = temporalAreaRadius_;
492 outPos_ = -1;
493 }
494
processImpl(Ptr<FrameSource> & frameSource,OutputArray _output)495 void BTVL1_CUDA::processImpl(Ptr<FrameSource>& frameSource, OutputArray _output)
496 {
497 if (outPos_ >= storePos_)
498 {
499 _output.release();
500 return;
501 }
502
503 readNextFrame(frameSource);
504
505 if (procPos_ < storePos_)
506 {
507 ++procPos_;
508 processFrame(procPos_);
509 }
510
511 ++outPos_;
512 const GpuMat& curOutput = at(outPos_, outputs_);
513
514 if (_output.kind() == _InputArray::CUDA_GPU_MAT)
515 curOutput.convertTo(_output.getGpuMatRef(), CV_8U);
516 else
517 {
518 curOutput.convertTo(finalOutput_, CV_8U);
519 arrCopy(finalOutput_, _output);
520 }
521 }
522
readNextFrame(Ptr<FrameSource> & frameSource)523 void BTVL1_CUDA::readNextFrame(Ptr<FrameSource>& frameSource)
524 {
525 frameSource->nextFrame(curFrame_);
526
527 if (curFrame_.empty())
528 return;
529
530 ++storePos_;
531 curFrame_.convertTo(at(storePos_, frames_), CV_32F);
532
533 if (storePos_ > 0)
534 {
535 std::pair<GpuMat, GpuMat>& forwardMotion = at(storePos_ - 1, forwardMotions_);
536 std::pair<GpuMat, GpuMat>& backwardMotion = at(storePos_, backwardMotions_);
537
538 opticalFlow_->calc(prevFrame_, curFrame_, forwardMotion.first, forwardMotion.second);
539 opticalFlow_->calc(curFrame_, prevFrame_, backwardMotion.first, backwardMotion.second);
540 }
541
542 curFrame_.copyTo(prevFrame_);
543 }
544
processFrame(int idx)545 void BTVL1_CUDA::processFrame(int idx)
546 {
547 const int startIdx = std::max(idx - temporalAreaRadius_, 0);
548 const int procIdx = idx;
549 const int endIdx = std::min(startIdx + 2 * temporalAreaRadius_, storePos_);
550
551 const int count = endIdx - startIdx + 1;
552
553 srcFrames_.resize(count);
554 srcForwardMotions_.resize(count);
555 srcBackwardMotions_.resize(count);
556
557 int baseIdx = -1;
558
559 for (int i = startIdx, k = 0; i <= endIdx; ++i, ++k)
560 {
561 if (i == procIdx)
562 baseIdx = k;
563
564 srcFrames_[k] = at(i, frames_);
565
566 if (i < endIdx)
567 srcForwardMotions_[k] = at(i, forwardMotions_);
568 if (i > startIdx)
569 srcBackwardMotions_[k] = at(i, backwardMotions_);
570 }
571
572 process(srcFrames_, at(idx, outputs_), srcForwardMotions_, srcBackwardMotions_, baseIdx);
573 }
574 }
575
createSuperResolution_BTVL1_CUDA()576 Ptr<SuperResolution> cv::superres::createSuperResolution_BTVL1_CUDA()
577 {
578 return makePtr<BTVL1_CUDA>();
579 }
580
581 #endif // HAVE_CUDA
582