【发布时间】:2021-03-19 14:08:57
【问题描述】:
我在使用 OpenCV 时正在编写一个 CUDA 程序。我有一个给定大小(例如 1000x800)的空垫,我使用 dataytpe CV_16SC3 显式转换为 GPUMat。需要在 CUDA 内核中以这种格式操作图像。但是,尝试操纵 Mat 似乎无法正常工作。
我按如下方式调用我的 CUDA 内核:
my_kernel <<< gridDim, blockDim >>>( (unsigned short*)img.data, img.cols, img.rows, img.step);
我的示例内核看起来像这样
__global__ void my_kernel( unsigned short* img, int width, int height, int img_step)
{
int x, y, pixel;
y = blockIdx.y * blockDim.y + threadIdx.y;
x = blockIdx.x * blockDim.x + threadIdx.x;
if (y >= height)
return;
if (x >= width)
return;
pixel = (y * (img_step)) + (3 * x);
img[pixel] = 255; //I know 255 is basically an uchar, this is just part of my test
img[pixel+1] = 255
img[pixel+2] = 255;
}
我期待这个小内核样本将所有像素写入白色。然而,在从 GPU 再次下载 Mat 并使用 imshow 对其进行可视化后,并非所有像素都是白色的,并且出现了一些奇怪的黑线,这让我相信我正在以某种方式写入无效的内存地址.
我的猜测如下。 OpenCV 文档指出 cv::mat::data 返回一个 uchar 指针。但是,我的 Mat 有一个数据类型“16U”(据我所知,短无符号)。这就是为什么在内核启动中我将指针转换为 (unsigned short*)。但显然这是不正确的。
我应该如何正确地在内核中读写 Mat 数据?
【问题讨论】: