-
-
Notifications
You must be signed in to change notification settings - Fork 56.5k
Description
System information (version)
Platform:
CPU: Intel 6th generation i5-6260U
GPU: Intel Iris Graphics 540 (Skylake GT3e)
OS: Linux Ubuntu 16.04 LTS x64
Compiler:
gcc: gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
OpenCL: intel-opencl-2.0-r4.0.59481
OpenCV:
OpenCV => 3.1.0
WITH_OPENCL true
Detailed description
The output vector of errors - err - in calcOpticalFlowPyrLK function has different result between the cpu and gpu code. Although both the cpu and gpu code follow the same algorithm, the implementation details are differnet. This reason cause the big calculation error of function output err between cpu and gpu. As 01org/libxcam project request, they need the result of err in their project. The gpu's invalid result of err cause the wrong result of libxcam project.
Furthermore, reviewing calcOpticalFlowPyrLK ocl test code in /modules/video/test/ocl/test_optflowpyrlk.cpp, there is also no test for the result of err.
Therefore, the calculation error of the result of the output err between the cpu and gpu is needed to be fixed.
Steps to reproduce
Just print the result of err from cpu and gpu code can find this problem.
With the patch showed below and running ./build/bin/opencv_test_video --gtest_filter=OCL_Video/PyrLKOpticalFlow*, this problem can also be reproduced.
diff --git a/modules/video/test/ocl/test_optflowpyrlk.cpp b/modules/video/test/ocl/test_optflowpyrlk.cpp
index 3c264a5..9387f9c 100644
--- a/modules/video/test/ocl/test_optflowpyrlk.cpp
+++ b/modules/video/test/ocl/test_optflowpyrlk.cpp
@@ -44,7 +44,7 @@
#include "../test_precomp.hpp"
#include "opencv2/ts/ocl_test.hpp"
-
+#include <iostream>
#ifdef HAVE_OPENCL
@@ -104,6 +104,7 @@ OCL_TEST_P(PyrLKOpticalFlow, Mat)
ASSERT_EQ(cpuStatusCPU.size(), status.size());
size_t mistmatch = 0;
+ size_t errmatch = 0;
for (size_t i = 0; i < nextPts.size(); ++i)
{
if (status[i] != cpuStatusCPU[i])
@@ -122,11 +123,15 @@ OCL_TEST_P(PyrLKOpticalFlow, Mat)
if (!eq || errdiff > 1e-1)
++mistmatch;
+
+ if(std::abs(cpuErr[i] - err[i]) > 0.01) {
+ ++errmatch;
+ }
}
}
double bad_ratio = static_cast<double>(mistmatch) / (nextPts.size());
-
+ std::cout << "misnumber: " << errmatch << std::endl;
ASSERT_LE(bad_ratio, eps);
}