提取一个连续的 OpenCV cuda::GpuMat?
Posted
技术标签:
【中文标题】提取一个连续的 OpenCV cuda::GpuMat?【英文标题】:extract a continuous OpenCV cuda::GpuMat? 【发布时间】:2021-05-08 04:16:00 【问题描述】:我正在尝试将推力算法应用于 cuda::GpuMats 中的数据。不幸的是,OpenCV 基本上从不产生连续的 GpuMat(这几乎破坏了我所有的算法、代码、性能等......)。通常,当我遇到这种主矩阵不连续的场景时,我只是克隆矩阵,通常当矩阵来自另一个矩阵的矩形视图时,主侧矩阵会变得不连续。
这...不适用于 gpu 垫。从字面上看,似乎从来没有连续出现。我不确定 OpenCV 到底发生了什么。我所做的只是:
cv::Mat host(600,400);
cv::gpu::GpuMat device;
device.upload(host);
cv::gpu::GpuMat continuous;
if(device.isContinuous())
continuous = device;
else
continuous = device.clone();
//always prints...
if(!continuous.isContinuous())
std::cout << "isn't Continuous\n";
如您所见,仅上传数据的行为就会产生不连续的数据...
【问题讨论】:
我认为这是一个选项:docs.opencv.org/3.1.0/d5/d8f/…。它创建了一个可用于 CUDA 推力 API 的迭代器。虽然它可能存在性能问题。我将它用于thrust::minmax_element
,它比仅下载到cv::Mat
并在 Jetson Nano 上正常执行要慢。这个问题很可能是因为它使用了除法。也许有更好的实现方式。
【参考方案1】:
嗨,亲爱的, 要生成连续的GpuMat,您可以使用以下方法之一:
-
使用
cv::cuda::createContinuous(int rows, int cols, int type, continuous_gpumat
) 或其重载。
使用cudaMalloc
cuda api调用或类似函数分配一个连续的Cuda内存,然后为这个连续缓冲区构造一个GpuMat header :// elem_size is depent on data type
int alloc_size = rows*cols*elem_size;
uchar *data = nullptr;
cudaError_t status = cudaMalloc(&data, alloc_size);
assert(status==cudaSuccess);
continuous_gpumat = cv::cuda::GpuMat(rows, cols, type, data);
// 在析构函数中:status = cudaFree(data);
assert(status==cudaSuccess);
【讨论】:
以上是关于提取一个连续的 OpenCV cuda::GpuMat?的主要内容,如果未能解决你的问题,请参考以下文章