代码之家  ›  专栏  ›  技术社区  ›  sam

OpenCV-将GpuMat复制到cuda设备数据中

  •  0
  • sam  · 技术社区  · 7 年前

    我想把数据复制到 cv::cuda::GpuMat 给一个 uint8_t* 要在内核中使用的变量。

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

    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);
    

    但产出并不如预期。下面分别是输入和输出图像。

    输入 Input Image

    输出 enter image description here

    我试过给 cv::Mat 来源于 cudaMemcpy . 它似乎工作得很好。问题似乎是 简历:cuda::GpuMat 库达门西 . 类似的问题在 here

    此外,如果图像是256或512,程序似乎工作正常。

    我错过了什么?要使752x480图像正常工作,应该做些什么?

    1 回复  |  直到 7 年前
        1
  •  3
  •   talonmies    7 年前

    OpenCV GpuMat使用跨步存储(因此图像不会连续存储在内存中)。简而言之,你的例子在大多数情况下都失败了,因为

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

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

    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、未经编译或测试、使用风险自负的人编写]

    只有当GpuMat的行间距与存储在矩阵中的类型的大小乘以列数时,代码才能正常工作。这很可能是两个圆幂的图像。