I would like to utilize OpenCV's integration of OpenGL/OpenCL to achieve fast distortion of images directly on the GPU while avoiding GPU/CPU image transfers. I can create a cv::ogl::Buffer
from an OpenGL buffer object in Qt:
// m_pub is of type QOpenGLBuffer
cv::ogl::Buffer b(512, 512, CV_8UC4, m_pub.bufferId());
But the next line throws an exception:
cv::UMat m = cv::ogl::mapGLBuffer(b);
The error reported by OpenCV was originally:
OpenCV(4.5.5) Error: Unknown error code -220 (OpenCL: clCreateFromGLBuffer failed) in cv::ogl::mapGLBuffer, file D:\OpenCV\opencv-4.5.5\modules\core\src\opengl.cpp, line 1886
To get further information, I call cv::ocl::getOpenCLErrorString(status);
in opengl.cpp, rebuild, and find that the error is CL_INVALID_CONTEXT.
I've checked cv::ocl::Context
, cv::ocl::Device
, cv::ocl::Platform
, added cv::ocl::attachContext
, all doesn't work. I'm stuck here, don't know how to go forward.
Any suggestions are really appreciated. Thanks.
CodePudding user response:
It needs to call cv::ogl::ocl::initializeContextFromGL()
in the initialization phase. My project is based on Qt, the window is inherited from QOpenGLWindow, so I call that function in initializeGL()
.
I guess that without this call, OpenCV would also create an OpenCL context automatically, but that's not the same as the one created from OpenGL, that's why the CL_INVALID_CONTEXT error occurred.
As a reminder, I used cv::remap
to process a 512x512 image and found that processing on the GPU via OpenCL was not much faster than on the CPU. It still takes around 12ms on average. This is still too slow if the application requires a high frame rate and needs to leave time for other processing.