获得对OpenCV GpuMat频道的访问权限

时间:2019-06-24 08:44:55

标签: c++ opencv cuda

我正在研究光线追踪器。我想通过使用GPU将每个像素的数据保存在OpenCV Mat中来优化代码。

现在,我将像素值保存在缓冲区fb中,该缓冲区是三个值(RGB)的向量:

__global__ void render(vec3 *fb, int max_x, int max_y, Camera **cam, Triangle *data, size_t n, )
{
    int i = threadIdx.x + blockIdx.x * blockDim.x;
    int j = threadIdx.y + blockIdx.y * blockDim.y;
    if ((i >= max_x) || (j >= max_y)) return;
    int pixel_index = j * max_x + i;
    float u = float(i) / float(max_x);
    float v = float(j) / float(max_y);
    Ray r = (*cam)->get_ray(u,v);
    fb[pixel_index] = color(r, data,n);
}

然后将数据保存在CPU上的Mat中:

for (int j = ny - 1; j >= 0; j--) 
{
    for (int i = 0; i < nx; i++) 
    {
        size_t pixel_index = j * nx + i;
        int ir = int(255.99*fb[pixel_index].r());
        int ig = int(255.99*fb[pixel_index].g());
        int ib = int(255.99*fb[pixel_index].b());
        output.at<Vec3b>(j, i)[0] = (uchar)ib;
        output.at<Vec3b>(j, i)[1] = (uchar)ig;
        output.at<Vec3b>(j, i)[2] = (uchar)ir;
        //std::cout << ir << " " << ig << " " << ib << "\n";
    }
}

但是当我有一个大像素阵列时,这是一个非常缓慢的过程。这就是为什么我要使用OpenCV GpuMat并将数据直接保存在GPU上的原因。

问题是我找不到一个如何在GPU Mat的每个通道中保存数据的示例。这是一种简单的方法,类似于将数据保存在CPU上吗?

2 个答案:

答案 0 :(得分:1)

请参见documentation。上面写着

  

没有函数返回对其数据的引用(因为GPU上的引用对CPU无效)

访问数据的唯一方法是通过data函数。但是只能在(cuda)内核代码中取消引用指针。而且没有 据我所知at的功能。因此,您将必须计算数据的偏移量。

答案 1 :(得分:0)

谢谢您的回答。他们让我思考如何以另一种方式来做。我不确定这是否是解决该问题的最佳解决方案,但它是否有效,我认为这是一种在GPU上填充矩阵的安静简便方法。

  1. 在GPU上为矩阵保留内存
Mat output(ny, nx, CV_8UC3);
    const size_t numBytes = output.step * output.rows;
    unsigned char *d_output;
    cudaMalloc<unsigned char>(&d_output, numBytes);
  1. GPU上的填充矩阵
_global__ void render(vec3 *fb, int max_x, int max_y, Camera **cam, Triangle *data, size_t n, unsigned char* input, int step)
{

    int i = threadIdx.x + blockIdx.x * blockDim.x;
    int j = threadIdx.y + blockIdx.y * blockDim.y;
    if ((i >= max_x) || (j >= max_y)) return;
    int pixel_index = j * max_x + i;
    int index = j * step + 3 * i;
    float u = float(i) / float(max_x);
    float v = float(j) / float(max_y);
    Ray r = (*cam)->get_ray(u,v);
    fb[pixel_index] = color(r, data,n);
    int ir = int(255.99*fb[pixel_index].r());
    int ig = int(255.99*fb[pixel_index].g());
    int ib = int(255.99*fb[pixel_index].b());


    input[index] = ib;
    input[index+1] = ig;
    input[index+2] = ir;


}

对于此代码的任何建议和评论,我将不胜感激。