我找不到任何参考,除了:
http://answers.opencv.org/question/9512/how-to-bind-gpumat-to-texture/
其中讨论了 CUDA 方法。
理想情况下,我想用 a 的内容更新 OpenGL 纹理cv::gpu::GpuMat
而不复制回 CPU,也不直接使用 CUDA(尽管我认为在添加此功能之前这可能是必要的)。
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(...);
好吧,这是我的理解,也许不是 100% 正确,并为我的非母语英语道歉。
GpuMat
使用全局内存。然而 OpenGL 纹理驻留在Texture Memory中,这是专门为 GPU 的纹理硬件(不是 CUDA 核心)设计的。纹理内存不是像通常的线性 2D/3D 数组那样组织,它可能使用某些空间填充曲线来组织其内容以优化纹理缓存速率。因此,您无法获得指向 Texture 的设备指针。您只能通过 Texture Fetch(Read Only) 或 Surface R/W 直接在 CUDA 中访问 Texture Mem。
目前的 OpenCV 实现似乎没有使用 cuda 纹理/表面特征。您必须从纹理复制到全局内存才能将它们绑定为GpuMat
s。好吧,不是一个“绑定”解决方案。
该线程描述了一种写入 OpenGL 纹理的 CUDA 方法。
要么等待 OpenCV 实现新功能,要么等待 NVIDIA 新的 GPU 架构统一 Texture Mem 和 Global Mem,要么等待有人发明一种特殊的 EMP 设备来破解这些记忆...... XD