clEnqueueCopyImageToBuffer 二维图像到一维数组

clEnqueueCopyImageToBuffer 2d image to 1d array

我正在尝试确定两个图像之间的 "error"(目前只是差的平方和。)我在我的第一个内核和 return 单个图像(黑色=完美匹配)中计算它, 白色=完美错误)。我现在想在第二个内核中将该图像缩小为单个 "error" 值。我的第一个游戏计划是将 "error" 图像传递给第二个内核以进行缩小,但我发现我不能 read/write 传递给同一内核中的图像...所以我想复制图像到缓冲区,我认为一维数组缓冲区上的缩减内核比二维数组更容易。我可以简单地将第一个内核的像素值 return 放入一维数组中,但我无法轻松调试(通过查看 returned,"error"图片。)

我找不到明确的答案,我的代码似乎可以编译并且 运行(还没有完成,只是几个构建步骤),但是我只是想确定 clEnqueueCopyImageToBuffer在我继续之前,可以将 2d 图像用于 1d 缓冲区副本。

伪代码:

// Create (or load) an OpenCV mat
Mat IMAGE (y, x, CV_32FC1, Scalar(0.0));
// Create the CL Image
image = clCreateImage2D(context, CL_MEM_READ_WRITE | CL_MEMCOPY_HOST_PTR, 
        & format, IMAGE.cols, IMAGE.rows,0,(void*)IMAGE.data, &err);
// Create a buffer to copy the image to after I do some work in a kernel
size_t image_size = {IMAGE.cols * IMAGE.rows * 1};
// Probably not the most correct way to create the buffer, but it works:     
image_mem = clCreateBuffer(context, CL_MEM_READ_WRITE |     
        CL_MEM_COPY_HOST_PTR, image_size,(void*)IMAGE.data, &err);
...
// Run first kernel on image then
clEnqueueCopyImageToBuffer(ocl_queue, image, image_mem,
         origin, region, 0, 0, NULL, NULL);
// Run second kernel on the buffer

这对我来说似乎是合乎逻辑的,但是我之前已经做出了合乎逻辑的假设。

谢谢!

是的,您当然可以将 2D 图像复制到 1D 缓冲区(无论如何,所有 OpenCL 缓冲区都是 1D)。

如果您的 OpenCV 图像类型是 CV_32FC1,那么您的 image_size 定义需要是 IMAGE.cols * IMAGE.rows * sizeof(float)

但是,为什么不对 2D 图像执行缩小,然后将最终结果写入缓冲区,而不是产生额外的副本? 2D 缩小的逻辑并不比 1D 缩小困难多少,并且这不需要您 read/write from/to 相同的图像。