Fastest way to make an UMat from an OpenGL texture -- am I doing it right?

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Fastest way to make an UMat from an OpenGL texture -- am I doing it right?

Oktay Ahıska
Hi everyone,

I am trying to apply OpenCV filters to an OpenGL texture, with the
output going to another pre-existing OpenGL texture. I have the
following code:

    // texId, texIdOut: ids of input/output textures
    // tiSize: texture dimensions

    using namespace cv::ogl;
    Texture2D texIn { tiSize[1], tiSize[0], Texture2D::RGBA, texId };
    Texture2D texOut{ tiSize[1], tiSize[0], Texture2D::RGBA, texIdOut };

    static cv::UMat uMatIn;
    static cv::UMat uMatOut;

    convertFromGLTexture2D ( texIn, uMatIn );
    cv::blur(uMatIn, uMatOut, cv::Size(5, 5));
    convertToGLTexture2D ( uMatOut, texOut );

This brings the speed of my app from around 1800 fps to around 200 fps,
which makes me think I'm doing something wrong as this is a very simple
operation. I'm wondering if I'm incurring some sort of unnecessary copy
somewhere, and if there is a more efficient way to do this. I'm using
OpenCV 3.4.5.

Thanks in advance for any help you folks can provide, it will be greatly
appreciated.

Oktay
Reply | Threaded
Open this post in threaded view
|

Re: Fastest way to make an UMat from an OpenGL texture -- am I doing it right?

kaolin
I’m a little surprised you’re getting as much as 200fps—reading textures out is one of the slowest things you can do, sadly. On the bright side, blurs are really “cheap” on-gpu … you could push that as a shader pretty quickly. I’m not sure if there’s a better way to do that. :/  

 Back in opencv2 there was a ::gpuMat … now it seems it’s only in cuda? https://stackoverflow.com/questions/26909194/where-are-the-gpu-functions-on-opencv-3-0 https://stackoverflow.com/questions/26909194/where-are-the-gpu-functions-on-opencv-3-0 … but maybe that’s all you need?
 

 https://docs.opencv.org/4.0.1/d1/d1e/group__cuda.html https://docs.opencv.org/4.0.1/d1/d1e/group__cuda.html

 

 …
 

 Probably you want this as the bridge instead of convertFromGLTexture?
 

 cv::ogl::mapGLBuffer https://docs.opencv.org/3.4/d2/d3c/group__core__opengl.html#gaa7595c713e3a7c389b84f0f8f2827d4b (const Buffer https://docs.opencv.org/3.4/d3/d68/classcv_1_1ogl_1_1Buffer.html &buffer, int accessFlags=ACCESS_READ https://docs.opencv.org/3.4/dc/d84/group__core__basic.html#ggabdab02e31fd5188960403458083ef6d3a39d5f615d02cac084ab1dd0cb4f7c221|ACCESS_WRITE https://docs.opencv.org/3.4/dc/d84/group__core__basic.html#ggabdab02e31fd5188960403458083ef6d3afcb8f7013ace1726cd1bbeea800bc7b6)   Maps Buffer https://docs.opencv.org/3.4/d3/d68/classcv_1_1ogl_1_1Buffer.htmlobject to process on CL side (convert to UMat https://docs.opencv.org/3.4/d7/d45/classcv_1_1UMat.html). More... https://docs.opencv.org/3.4/d2/d3c/group__core__opengl.html#gaa7595c713e3a7c389b84f0f8f2827d4b
 

 

 https://docs.opencv.org/3.4/d2/d3c/group__core__opengl.html https://docs.opencv.org/3.4/d2/d3c/group__core__opengl.html

 

 Sorry that my links are all over the place, and sorry if you’ve already tried this….
 

Reply | Threaded
Open this post in threaded view
|

Re: Fastest way to make an UMat from an OpenGL texture -- am I doing it right?

Oktay Ahıska
In reply to this post by Oktay Ahıska

>     Posted by:  [hidden email]
>     Date: Mon Mar 18, 2019 12:30 pm ((PDT))
>
> I’m a little surprised you’re getting as much as 200fps—reading
> textures out is one of the slowest things you can do, sadly. On the
> bright side, blurs are really “cheap” on-gpu … you could push that as
> a shader pretty quickly. I’m not sure if there’s a better way to do
> that. :/

Yeah, that was a simple test case, something really simple but visible
so I could time it. When I do the same thing in glsl, there's hardly any
change in the frame rate.

>  Back in opencv2 there was a ::gpuMat … now it seems it’s only in
> cuda?
> ....
>  Probably you want this as the bridge instead of convertFromGLTexture?
>  cv::ogl::mapGLBuffer
> ....

I spent some time going the Cuda route in 2.xx, and I managed to pass
the texture to Cuda without a copy, but I was never able to get it into
OpenCV without copying. I've been playing around with the buffer
approach but when I call mapGLBuffer, I get an exception saying
something like "object is not a buffer".  Still, from what you say (and
my gut feeling), I think the answer lies with buffers, I just need to
figure out the proper OpenGL magic. (I tried it with a frame buffer, I
suppose a pixel buffer would have been the better choice.)

Thank you for your help, it is much appreciated,
Oktay