# Qt+OpenCV use cv::ogl::texture2D::copyFrom( cv::cuda::GpuMat) to get texture directly

**URL:** <https://forum.opencv.org/t/qt-opencv-use-cv-copyfrom-cv-gpumat-to-get-texture-directly/9400>\
**Category:** C++\
**Tags:** gpu, cuda\
**Created:** [July 5, 2022, 9:01am UTC](https://forum.opencv.org/t/qt-opencv-use-cv-copyfrom-cv-gpumat-to-get-texture-directly/9400 "2022-07-05T09:01:00Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Touch](https://avatars.discourse-cdn.com/v4/letter/t/51bf81/32.png) [@Touch](https://forum.opencv.org/u/Touch)\
**Post date:** [July 5, 2022, 9:01am UTC](https://forum.opencv.org/t/qt-opencv-use-cv-copyfrom-cv-gpumat-to-get-texture-directly/9400/1 "2022-07-05T09:01:00Z")

</div>

I am writing a module which gets `cv::cuda::GpuMat` data on gpu and draw it on `QOpenGLWidget`. To accelarate the speed, I want to avoid downloading data from device to host.

This is the main code

```auto
void MyPainter::drawImage(QMatrix4x4 transform_matrix, const cv::Mat &img)
{
    if(parent->context() == 0){
        parent->makeCurrent();
    }

    shader_program->bind();

    cv::cuda::GpuMat gpumat_img;
    qDebug() << "upload img....";
    gpumat_img.upload(img); // for test, because other modules are unfished
    qDebug() << gpumat_img.empty() << gpumat_img.type() << "Finish upload";
    qDebug() << gpumat_img.size().width << gpumat_img.size().height;

    cv::ogl::Texture2D test_texture;
    qDebug() << "copy to texture memory....";
    test_texture.copyFrom(gpumat_img); // here raise an error. 

    qDebug() << "Finish copy";

    test_texture.bind();
    vbo.bind();

    qDebug() << test_texture.size().width << test_texture.size().height;
    shader_program->setUniformValue("matrix", transform_matrix);
    shader_program->enableAttributeArray(MYSHADER_VERTEX_ATTRIBUTE);
    shader_program->enableAttributeArray(MYSHADER_TEXCOORD_ATTRIBUTE);
    shader_program->setAttributeBuffer(MYSHADER_VERTEX_ATTRIBUTE, GL_FLOAT, 0, 2);
    shader_program->setAttributeBuffer(MYSHADER_TEXCOORD_ATTRIBUTE, GL_FLOAT, 0, 2);

    QOpenGLFunctions *gl_function_ptr = QOpenGLContext::currentContext()->functions();
    gl_function_ptr->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

    shader_program->release();
    test_texture.release();
    vbo.release();

}

```

The error tells **“OpenCV(4.6.0) Error: Gpu API call (OS call failed or operation not supported on this OS) in `anonymous-namespace’::CudaResource::registerBuffer, file D:\lib\opencv\_my\source\opencv-4.6.0\modules\core\src\opengl.cpp, line 176”**

But if I use the `cv::ogl::texture2D::copyFrom(cv::Mat)` instead of `cv::ogl::texture2D::copyFrom(cv::cuda::GpuMat)`, it can work well.

I read some source code of opencv and find the error is appear at here:

```auto
    void CudaResource::registerBuffer(GLuint buffer)
    {
        CV_DbgAssert( buffer != 0 );

        if (buffer_ == buffer)
            return;

        cudaGraphicsResource_t resource;
        cudaSafeCall( cudaGraphicsGLRegisterBuffer(&resource, buffer, cudaGraphicsMapFlagsNone) ); // here raise the error

        release();

        resource_ = resource;
        buffer_ = buffer;
    }

```

But i can’t find `cudaGraphicsGLRegisterBuffer()`.

My environment

```auto
Qt 7.0.0
OpenCV 4.6.0
CUDA 11.6

```

Apologize for my poor English.

---

<div class="post-metadata">

**Author:** ![cudawarped](https://avatars.discourse-cdn.com/v4/letter/c/9dc877/32.png) [@cudawarped](https://forum.opencv.org/u/cudawarped)\
**Post date:** [July 5, 2022, 4:53pm UTC](https://forum.opencv.org/t/qt-opencv-use-cv-copyfrom-cv-gpumat-to-get-texture-directly/9400/2 "2022-07-05T16:53:50Z")

</div>

This is something I’ve wanted to try for ages, so please let me know how you get on.

Regarding the error, have you checked the [test cases](https://github.com/opencv/opencv_contrib/blob/9d0a451bee4cdaf9d3f76912e5abac6000865f1a/modules/cudaarithm/test/test_opengl.cpp#L311)? I had a quick look and didn’t get any errors from

```auto
cv::namedWindow("test", cv::WINDOW_OPENGL);
const Size sz(128, 128);
cv::cuda::GpuMat tmp(sz, CV_8UC1);
cv::ogl::Texture2D tex(sz, cv::ogl::Texture2D::DEPTH_COMPONENT, true);
tex.copyFrom(tmp, true);

```

---

<div class="post-metadata">

**Author:** ![Touch](https://avatars.discourse-cdn.com/v4/letter/t/51bf81/32.png) [@Touch](https://forum.opencv.org/u/Touch)\
**Post date:** [July 6, 2022, 9:02am UTC](https://forum.opencv.org/t/qt-opencv-use-cv-copyfrom-cv-gpumat-to-get-texture-directly/9400/3 "2022-07-06T09:02:30Z")

</div>

Thanks! And I tried the code you given. But it shows the same error

```auto
OpenCV: terminate handler is called! The last OpenCV error is:
OpenCV(4.6.0) Error: Gpu API call (OS call failed or operation not supported on this OS) in `anonymous-namespace'::CudaResource::registerBuffer, file D:\lib\opencv_my\source\opencv-4.6.0\modules\core\src\opengl.cpp, line 176

```

I guess it is because of the cuda environment, but I can’t find more information about the error.

!!! I use the same code in my vs+cuda+opencv project. And it can work without error and show an image.

```auto
	cv::Mat mat_img;
	mat_img = cv::imread("C:/Users/Touch/Desktop/0.jpg");
	cv::namedWindow("test", cv::WINDOW_OPENGL);
	cv::cuda::GpuMat tmp;
	tmp.upload(mat_img);
	cv::ogl::Texture2D tex;
	tex.copyFrom(tmp, true);
	cv::imshow("test", tex);
	cv::waitKey(0);

```

---

<div class="post-metadata">

**Author:** ![cudawarped](https://avatars.discourse-cdn.com/v4/letter/c/9dc877/32.png) [@cudawarped](https://forum.opencv.org/u/cudawarped)\
**Post date:** [July 6, 2022, 9:18am UTC](https://forum.opencv.org/t/qt-opencv-use-cv-copyfrom-cv-gpumat-to-get-texture-directly/9400/4 "2022-07-06T09:18:57Z")

</div>

Can you run `bin\opencv_test_cudaarithm.exe --gtest_filter=OpenGL/Texture2D.Constructor1/0` without errors? e.g.

> [RUN] OpenGL/Texture2D.Constructor1/0, where GetParam() = (128x128, 8UC1)  
> [OK] OpenGL/Texture2D.Constructor1/0 (2926 ms)  
> [----------] 1 test from OpenGL/Texture2D (2927 ms total)
> 
> [----------] Global test environment tear-down  
> [==========] 1 test from 1 test case ran. (3090 ms total)  
> [PASSED] 1 test.

Do any of the tests from opencv\_test\_cudaarithm.exe report that they have `PASSED`

---

<div class="post-metadata">

**Author:** ![Touch](https://avatars.discourse-cdn.com/v4/letter/t/51bf81/32.png) [@Touch](https://forum.opencv.org/u/Touch)\
**Post date:** [July 6, 2022, 9:30am UTC](https://forum.opencv.org/t/qt-opencv-use-cv-copyfrom-cv-gpumat-to-get-texture-directly/9400/5 "2022-07-06T09:30:03Z")

</div>

Yes i can pass the test.

```auto
OpenCV version: 4.6.0
OpenCV VCS version: unknown
Build type: Debug Release
WARNING: build value differs from runtime: Release
Compiler: C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.32.31326/bin/Hostx64/x64/cl.exe (ver 19.32.31329.0)
Parallel framework: ms-concurrency (nthreads=16)
CPU features: SSE? SSE2? SSE3?
Intel(R) IPP version: disabled
OpenCL is disabled
TEST: Skip tests with tags: 'mem_6gb', 'verylong'
Note: Google Test filter = OpenGL/Texture2D.Constructor1/0
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from OpenGL/Texture2D
[RUN] OpenGL/Texture2D.Constructor1/0, where GetParam() = (128x128, 8UC1)
[OK] OpenGL/Texture2D.Constructor1/0 (3 ms)
[----------] 1 test from OpenGL/Texture2D (3 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (172 ms total)
[PASSED] 1 test.

```

I guess the problem is on my qt project environment. Because my visual studio project with opencv+cuda doesn’t have the error.

---

<div class="post-metadata">

**Author:** ![cudawarped](https://avatars.discourse-cdn.com/v4/letter/c/9dc877/32.png) [@cudawarped](https://forum.opencv.org/u/cudawarped)\
**Post date:** [July 6, 2022, 9:31am UTC](https://forum.opencv.org/t/qt-opencv-use-cv-copyfrom-cv-gpumat-to-get-texture-directly/9400/6 "2022-07-06T09:31:50Z")

</div>

Let me know if you solve the problem, I will try later in a QT project to see if I get the same issue.

---

<div class="post-metadata">

**Author:** ![Touch](https://avatars.discourse-cdn.com/v4/letter/t/51bf81/32.png) [@Touch](https://forum.opencv.org/u/Touch)\
**Post date:** [July 6, 2022, 11:17am UTC](https://forum.opencv.org/t/qt-opencv-use-cv-copyfrom-cv-gpumat-to-get-texture-directly/9400/7 "2022-07-06T11:17:50Z")

</div>

OK but i haven’t found any solution yet. 😂

---

<div class="post-metadata">

**Author:** ![cudawarped](https://avatars.discourse-cdn.com/v4/letter/c/9dc877/32.png) [@cudawarped](https://forum.opencv.org/u/cudawarped)\
**Post date:** [July 6, 2022, 1:34pm UTC](https://forum.opencv.org/t/qt-opencv-use-cv-copyfrom-cv-gpumat-to-get-texture-directly/9400/8 "2022-07-06T13:34:16Z")

</div>

I don’t get any errors in QT running the test code in a class derived from QLabel.

---

<div class="post-metadata">

**Author:** ![Touch](https://avatars.discourse-cdn.com/v4/letter/t/51bf81/32.png) [@Touch](https://forum.opencv.org/u/Touch)\
**Post date:** [July 7, 2022, 2:29am UTC](https://forum.opencv.org/t/qt-opencv-use-cv-copyfrom-cv-gpumat-to-get-texture-directly/9400/9 "2022-07-07T02:29:59Z")

</div>

wow. I create a clickbutton on mainWidget and connect the signal and the test code as slot funtion. I think this doesn’t matter.  
Could you please show me you `.pro` file?  
And this is my `.prg` file.

```auto
QT += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++17

# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

# ===========opengl==============
QT += opengl
QT += core gui openglwidgets
QT += widgets
# ===============================

# ============opencv=============
INCLUDEPATH += D:\lib\opencv_my\build\install\include
#LIBS += D:\lib\opencv_my\build\install\x64\vc17\lib
LIBS += D:\lib\opencv_my\build\install\x64\vc17\lib\opencv_world460.lib
# ===============================

# ============eigen============
INCLUDEPATH += D:\lib\eigen-3.4.0
# =============================

# ============cuda=============
CUDA_DIR = $$(CUDA_PATH)
#message($${CUDA_DIR})
INCLUDEPATH += $${CUDA_DIR}/include
# =============================

# ============vtk==============
#LIBS += D:\lib\VTK-8.2.0\build\install_prefix\lib

# =============================

DISTFILES += \
    draw_image.frag \
    draw_image.vert

```
