OpenCV-将GpuMat复制到cuda设备数据 [英] OpenCV - Copy GpuMat into cuda device data

查看:1317
本文介绍了OpenCV-将GpuMat复制到cuda设备数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将cv::cuda::GpuMat中的数据复制到要在内核中使用的uint8_t*变量中.

I am trying to copy the data in a cv::cuda::GpuMat to a uint8_t* variable which is to be used in a kernel.

GpuMat包含分辨率为752x480且类型为CV_8UC1的图像数据.下面是示例代码:

The GpuMat contains an image data of resolution 752x480 and of type CV_8UC1. Below is the sample code:

uint8_t *imgPtr;
cv::Mat left, downloadedLeft;
cv::cuda::GpuMat gpuLeft;

left = imread("leftview.jpg", cv::IMREAD_GRAYSCALE);
gpuLeft.upload(left);

cudaMalloc((void **)&imgPtr, sizeof(uint8_t)*gpuLeft.rows*gpuLeft.cols);
cudaMemcpyAsync(imgPtr, gpuLeft.ptr<uint8_t>(), sizeof(uint8_t)*gpuLeft.rows*gpuLeft.cols, cudaMemcpyDeviceToDevice);

// following code is just for testing and visualization...
cv::cuda::GpuMat gpuImg(left.rows, left.cols, left.type(), imgPtr);
gpuImg.download(downloadedLeft);
imshow ("test", downloadedLeft);
waitKey(0);

但是输出不符合预期.以下分别是输入图像和输出图像.

But the output is not as expected. Following are the input and output image respectively.

输入

输出

我尝试将cv::Mat源提供给cudaMemcpy.它似乎工作正常.问题似乎出在cv::cuda::GpuMatcudaMemcpy上.

I have tried giving the cv::Mat source to the cudaMemcpy. It seems to be working fine. The issue seems to be with the cv::cuda::GpuMat and cudaMemcpy. A similar issue is discussed in the here

此外,如果的图像为256或512,则该程序似乎运行正常.

Also, if the image with is 256 or 512, the program seems to be working fine.

我想念的是什么?要使752x480图像正常工作,应该怎么做?

What is that I am missing? What should be done for the 752x480 image to work properly?

推荐答案

OpenCV GpuMat使用分段存储(因此映像不会连续存储在内存中).简而言之,您的示例在大多数情况下都会失败,因为

OpenCV GpuMat uses strided storage (so the image is not stored contiguously in memory). In short, your example fails for most cases because

  1. 您不会将整个映像复制到CUDA内存分配中,并且
  2. 从GPU指针创建第二个GpuMat实例时,您没有正确指定内存布局.

通过阅读文档,您可能想要这样的东西:

By my reading of the documentation, you probably want something like this:

uint8_t *imgPtr;
cv::Mat left, downloadedLeft;
cv::cuda::GpuMat gpuLeft;

left = imread("leftview.jpg", cv::IMREAD_GRAYSCALE);
gpuLeft.upload(left);

cudaMalloc((void **)&imgPtr, gpuLeft.rows*gpuLeft.step);
cudaMemcpyAsync(imgPtr, gpuLeft.ptr<uint8_t>(), gpuLeft.rows*gpuLeft.step, cudaMemcpyDeviceToDevice);

// following code is just for testing and visualization...
cv::cuda::GpuMat gpuImg(left.rows, left.cols, left.type(), imgPtr, gpuLeft.step);
gpuImg.download(downloadedLeft);
imshow ("test", downloadedLeft);
waitKey(0);

[由从未使用过OpenCV,未经编译或测试,使用自担风险的人撰写]

[Written by someone who has never used OpenCV, not compiled or tested, use at own risk]

只有当GpuMat的行间距意外地等于列数乘以矩阵中存储的类型大小时,代码才能正常工作.这可能是尺寸约为2的幂的图像.

The only time your code would work correctly would be when the row pitch of the GpuMat was serendipitously the same as the number of columns times the size of the type stored in the matrix. This is likely to be images with sizes which are round powers of two.

这篇关于OpenCV-将GpuMat复制到cuda设备数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆