Skip to content

Commit 1c6b74d

Browse files
committed
[moved from opencv] Fix Farneback Optical Flow Algorithm
- Before this PR, following tests failed on some platform. CUDA_OptFlow/FarnebackOpticalFlow.Accuracy/19 CUDA_OptFlow/FarnebackOpticalFlow.Accuracy/23 - The algorithm now recognizes the OPTFLOW_USE_INITIAL_FLOW flag. Previously, when the flag was set, it did not use the flow data passed as input, instead used some garbage data in memory. - More strict test limit. original commit: opencv/opencv@4366c87
1 parent ab2e832 commit 1c6b74d

File tree

2 files changed

+31
-8
lines changed

2 files changed

+31
-8
lines changed

modules/cudaoptflow/src/farneback.cpp

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -165,10 +165,29 @@ namespace
165165
{
166166
const GpuMat frame0 = _frame0.getGpuMat();
167167
const GpuMat frame1 = _frame1.getGpuMat();
168+
GpuMat flow = _flow.getGpuMat();
168169

169-
BufferPool pool(stream);
170-
GpuMat flowx = pool.getBuffer(frame0.size(), CV_32FC1);
171-
GpuMat flowy = pool.getBuffer(frame0.size(), CV_32FC1);
170+
CV_Assert(frame0.channels() == 1 && frame1.channels() == 1);
171+
CV_Assert(frame0.size() == frame1.size());
172+
173+
GpuMat flowx, flowy;
174+
175+
// If flag is set, check for integrity; if not set, allocate memory space
176+
if (flags_ & OPTFLOW_USE_INITIAL_FLOW)
177+
{
178+
CV_Assert(flow.size() == frame0.size() && flow.channels() == 2 &&
179+
flow.depth() == CV_32F);
180+
181+
std::vector<cuda::GpuMat> _flows(2);
182+
cuda::split(flow, _flows, stream);
183+
flowx = _flows[0];
184+
flowy = _flows[1];
185+
}
186+
else
187+
{
188+
flowx.create(frame0.size(), CV_32FC1);
189+
flowy.create(frame0.size(), CV_32FC1);
190+
}
172191

173192
calcImpl(frame0, frame1, flowx, flowy, stream);
174193

@@ -291,8 +310,6 @@ namespace
291310

292311
void FarnebackOpticalFlowImpl::calcImpl(const GpuMat &frame0, const GpuMat &frame1, GpuMat &flowx, GpuMat &flowy, Stream &stream)
293312
{
294-
CV_Assert(frame0.channels() == 1 && frame1.channels() == 1);
295-
CV_Assert(frame0.size() == frame1.size());
296313
CV_Assert(polyN_ == 5 || polyN_ == 7);
297314
CV_Assert(!fastPyramids_ || std::abs(pyrScale_ - 0.5) < 1e-6);
298315

@@ -303,8 +320,6 @@ namespace
303320
Size size = frame0.size();
304321
GpuMat prevFlowX, prevFlowY, curFlowX, curFlowY;
305322

306-
flowx.create(size, CV_32F);
307-
flowy.create(size, CV_32F);
308323
GpuMat flowx0 = flowx;
309324
GpuMat flowy0 = flowy;
310325

modules/cudaoptflow/test/test_optflow.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,15 @@ CUDA_TEST_P(FarnebackOpticalFlow, Accuracy)
337337
frame0, frame1, flow, farn->getPyrScale(), farn->getNumLevels(), farn->getWinSize(),
338338
farn->getNumIters(), farn->getPolyN(), farn->getPolySigma(), farn->getFlags());
339339

340-
EXPECT_MAT_SIMILAR(flow, d_flow, 0.1);
340+
// Relax test limit when the flag is set
341+
if (farn->getFlags() & cv::OPTFLOW_FARNEBACK_GAUSSIAN)
342+
{
343+
EXPECT_MAT_SIMILAR(flow, d_flow, 2e-2);
344+
}
345+
else
346+
{
347+
EXPECT_MAT_SIMILAR(flow, d_flow, 1e-4);
348+
}
341349
}
342350

343351
INSTANTIATE_TEST_CASE_P(CUDA_OptFlow, FarnebackOpticalFlow, testing::Combine(

0 commit comments

Comments
 (0)