- 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.
{
const GpuMat frame0 = _frame0.getGpuMat();
const GpuMat frame1 = _frame1.getGpuMat();
+ GpuMat flow = _flow.getGpuMat();
- BufferPool pool(stream);
- GpuMat flowx = pool.getBuffer(frame0.size(), CV_32FC1);
- GpuMat flowy = pool.getBuffer(frame0.size(), CV_32FC1);
+ CV_Assert(frame0.channels() == 1 && frame1.channels() == 1);
+ CV_Assert(frame0.size() == frame1.size());
+
+ GpuMat flowx, flowy;
+
+ // If flag is set, check for integrity; if not set, allocate memory space
+ if (flags_ & OPTFLOW_USE_INITIAL_FLOW)
+ {
+ CV_Assert(flow.size() == frame0.size() && flow.channels() == 2 &&
+ flow.depth() == CV_32F);
+
+ std::vector<cuda::GpuMat> _flows(2);
+ cuda::split(flow, _flows, stream);
+ flowx = _flows[0];
+ flowy = _flows[1];
+ }
+ else
+ {
+ flowx.create(frame0.size(), CV_32FC1);
+ flowy.create(frame0.size(), CV_32FC1);
+ }
calcImpl(frame0, frame1, flowx, flowy, stream);
void FarnebackOpticalFlowImpl::calcImpl(const GpuMat &frame0, const GpuMat &frame1, GpuMat &flowx, GpuMat &flowy, Stream &stream)
{
- CV_Assert(frame0.channels() == 1 && frame1.channels() == 1);
- CV_Assert(frame0.size() == frame1.size());
CV_Assert(polyN_ == 5 || polyN_ == 7);
CV_Assert(!fastPyramids_ || std::abs(pyrScale_ - 0.5) < 1e-6);
Size size = frame0.size();
GpuMat prevFlowX, prevFlowY, curFlowX, curFlowY;
- flowx.create(size, CV_32F);
- flowy.create(size, CV_32F);
GpuMat flowx0 = flowx;
GpuMat flowy0 = flowy;
frame0, frame1, flow, farn->getPyrScale(), farn->getNumLevels(), farn->getWinSize(),
farn->getNumIters(), farn->getPolyN(), farn->getPolySigma(), farn->getFlags());
- EXPECT_MAT_SIMILAR(flow, d_flow, 0.1);
+ // Relax test limit when the flag is set
+ if (farn->getFlags() & cv::OPTFLOW_FARNEBACK_GAUSSIAN)
+ {
+ EXPECT_MAT_SIMILAR(flow, d_flow, 2e-2);
+ }
+ else
+ {
+ EXPECT_MAT_SIMILAR(flow, d_flow, 1e-4);
+ }
}
INSTANTIATE_TEST_CASE_P(CUDA_OptFlow, FarnebackOpticalFlow, testing::Combine(
Size size = frame0.size();
UMat prevFlowX, prevFlowY, curFlowX, curFlowY;
- flowx.create(size, CV_32F);
- flowy.create(size, CV_32F);
UMat flowx0 = flowx;
UMat flowy0 = flowy;
return false;
std::vector<UMat> flowar;
- if (!_flow0.empty())
+
+ // If flag is set, check for integrity; if not set, allocate memory space
+ if (flags_ & OPTFLOW_USE_INITIAL_FLOW)
+ {
+ if (_flow0.empty() || _flow0.size() != _prev0.size() || _flow0.channels() != 2 ||
+ _flow0.depth() != CV_32F)
+ return false;
split(_flow0, flowar);
+ }
else
{
- flowar.push_back(UMat());
- flowar.push_back(UMat());
+ flowar.push_back(UMat(_prev0.size(), CV_32FC1));
+ flowar.push_back(UMat(_prev0.size(), CV_32FC1));
}
if(!this->operator()(_prev0.getUMat(), _next0.getUMat(), flowar[0], flowar[1])){
return false;
CV_Assert( prev0.size() == next0.size() && prev0.channels() == next0.channels() &&
prev0.channels() == 1 && pyrScale_ < 1 );
- _flow0.create( prev0.size(), CV_32FC2 );
+
+ // If flag is set, check for integrity; if not set, allocate memory space
+ if( flags_ & OPTFLOW_USE_INITIAL_FLOW )
+ CV_Assert( _flow0.size() == prev0.size() && _flow0.channels() == 2 &&
+ _flow0.depth() == CV_32F );
+ else
+ _flow0.create( prev0.size(), CV_32FC2 );
+
Mat flow0 = _flow0.getMat();
for( k = 0, scale = 1; k < levels; k++ )