How to convert OpenCV texture to ofTexture

Hi everyone! I’m currently working with OpenCV and I have a GpuMat I want to directly convert to a texture. In opencv, I can create a cv::ogl::Texture2D tex and then call tex.copyFrom(GpuMat). At this point, I know it is somewhere in the VRAM but I’m not so sure how to access it from OF.

Since ofTexture is also a wrapper around openGL’s texture, is there a way I can pass it to OF to draw?


I think so!

Two possible approaches.
1 - use this function of ofTexture. With this call cv::ogl::Texture2D::texId()
( I am not sure if it will work though due to OpenCV maybe having its own GL context? )
2 - Use cv::ogl::Texture2D::copyTo, to copy to a cv::Mat and then load that data to ofPixels and then to a texture.

Thanks for the suggestions! I tried both methods. I even tried to use the loadData + ofTextureData with GpuMat’s data pointer. Still, I couldn’t get it to work as I’ve run into a few errors on the openCV side. It may be a bug or a platform specific thing, though my code could compile, I get a runtime error when I use openCV’s texture2D copyFrom() from a GpuMat. I’ll have to investigate further…

@theo A little late to this thread I suppose but you are right about the 1st use case.
I think cv uses its own opengl context. Since I am not using GMat but UMat (openCL) I tried to force it like this

   //Somewhere in the contstructor
    vector<cl::Platform> platforms;
    assert(platforms.size() > 0);
    // This is just for me to make sure it uses dGPU
    std::string card = "NVID";
    cl::Platform myPlatform;
    cl::Device myDevice;
    cl::Context myContext;

    for (cl::Platform platform : platforms) {
        std::vector<cl::Device> devices;
        std::string pName = platform.getInfo<CL_PLATFORM_NAME>();
        if (pName.find(card) != std::string::npos) {
            platform.getDevices(CL_DEVICE_TYPE_ALL, &devices);
            myPlatform = platform;
            myDevice = devices.front();
    cl_context_properties properties[] = {
        CL_GL_CONTEXT_KHR, (cl_context_properties)glXGetCurrentContext(),
        CL_GLX_DISPLAY_KHR, (cl_context_properties)glXGetCurrentDisplay(),
        CL_CONTEXT_PLATFORM, (cl_context_properties)m_Platform(), 0
    myContext = cl::Context(m_Device, properties);
    // cv::ocl::useOpenCL(); - //Maybe unnecessary
    cv::ocl::attachContext(myPlatform.getInfo<CL_PLATFORM_NAME>(), myPlatform(), myContext(), m_Device());
    // cv::ocl::Context(myContext); // Alternative to the above line

Still no luck.
Any ideas?

I am having the same problem even when I try to share openGL and OpenCL context with OF. My projects that run on my custom GL abstraction layer share the context just fine. but openCL cant seem to have access to context created by OpenFrameworks

I have also tried setting the context pointers this way

    cl_context_properties properties[]
        = {
              CL_GL_CONTEXT_KHR, (cl_context_properties)ofGetWindowPtr()->getGLXContext(),
              CL_GLX_DISPLAY_KHR, (cl_context_properties)ofGetWindowPtr()->getX11Display(),
              CL_CONTEXT_PLATFORM, (cl_context_properties)(platforms[0])(), 0

Still no luck