9

我找不到任何参考,除了:

http://answers.opencv.org/question/9512/how-to-bind-gpumat-to-texture/

其中讨论了 CUDA 方法。

理想情况下,我想用 a 的内容更新 OpenGL 纹理cv::gpu::GpuMat而不复制回 CPU,也不直接使用 CUDA(尽管我认为在添加此功能之前这可能是必要的)。

4

2 回答 2

12

OpenCV 支持 OpenGL。见opencv2/core/opengl_interop.hpp头文件。您可以将 GpuMat 的内容复制到 Texture:

cv::gpu::GpuMat d_mat(768, 1024, CV_8UC3);
cv::ogl::Texture2D tex;
tex.copyFrom(d_mat);
tex.bind();
// draw something

你也可以使用cv::ogl::Buffer类。它是 OpenGL 缓冲存储器的包装器。此内存可以映射到 CUDA 内存而无需内存复制:

cv::ogl::Buffer ogl_buf(1, 1000, CV_32FC3);
cv::gpu::GpuMat d_mat = ogl_buf.mapDevice();
// fill d_mat with CUDA
ogl_buf.unmapDevice();
// use ogl_buf in OpenGL
ogl_buf.bind(cv::ogl::Buffer::ARRAY_BUFFER);
glDrawArray(...);
于 2013-08-07T14:49:03.033 回答
4

好吧,这是我的理解,也许不是 100% 正确,并为我的非母语英语道歉。

GpuMat使用全局内存。然而 OpenGL 纹理驻留在Texture Memory中,这是专门为 GPU 的纹理硬件(不是 CUDA 核心)设计的。纹理内存不是像通常的线性 2D/3D 数组那样组织,它可能使用某些空间填充曲线来组织其内容以优化纹理缓存速率。因此,您无法获得指向 Texture 的设备指针。您只能通过 Texture Fetch(Read Only) 或 Surface R/W 直接在 CUDA 中访问 Texture Mem。

目前的 OpenCV 实现似乎没有使用 cuda 纹理/表面特征。您必须从纹理复制到全局内存才能将它们绑定为GpuMats。好吧,不是一个“绑定”解决方案。

该线程描述了一种写入 OpenGL 纹理的 CUDA 方法。

要么等待 OpenCV 实现新功能,要么等待 NVIDIA 新的 GPU 架构统一 Texture Mem 和 Global Mem,要么等待有人发明一种特殊的 EMP 设备来破解这些记忆...... XD

于 2013-09-18T04:45:28.173 回答