Cuda 内核代码未涵盖所有图像

问题描述 投票:0回答:1

我正在尝试通过编写 cuda 内核代码来均衡直方图。主要问题是,在图像的某一行之前操作似乎是正确的,之后输出是错误的,但我不明白为什么,下面是代码和图像。

预期输出:

获得的输出:

我不明白为什么,我已经检查过直方图包含准确的值,实际上预期的输出是通过在CPU上执行操作获得的,我没有问题,只要我通过“获得的输出”到GPU的图像就是结果。现在我展示代码

Cuda 内核代码

__global__ void equalizeHistCUDA(unsigned char* input, unsigned char* output, int *cumulative_hist, int cols, int rows) {
    int nGrayLevels = 256, area = cols*rows;
    int i = blockIdx.y * blockDim.y + threadIdx.y;
    int j = blockIdx.x * blockDim.x + threadIdx.x;
    if (i < rows && j < cols){  
        int pixelValue = input[i * cols + j];
        output[i * cols + j] = static_cast<uchar>((static_cast<double>(nGrayLevels) / area) * cumulative_hist[pixelValue]);
    }
}

部分主体

nThreadPerBlocco = dim3(4, 3);
    numBlocks.y = gpu_resizedImage.rows / nThreadPerBlocco.y + ((gpu_resizedImage.rows % nThreadPerBlocco.y) == 0 ? 0 : 1);
    numBlocks.x = gpu_resizedImage.cols / nThreadPerBlocco.x + ((gpu_resizedImage.cols % nThreadPerBlocco.x) == 0 ? 0 : 1);
    cv::cuda::GpuMat gpu_equalizedImage(600,600,CV_8UC1);
equalizeHistCUDA<<<numBlocks,nThreadPerBlocco>>>(gpu_resizedImage.data,gpu_equalizedImage.data,cumHist_device,gpu_resizedImage.cols,gpu_resizedImage.rows);
    cudaDeviceSynchronize();
    cudaError_t cudaErr = cudaGetLastError();
    if (cudaErr != cudaSuccess)
        fprintf(stderr, "Errore CUDA: %s\n", cudaGetErrorString(cudaErr));

    cv::Mat img;
    gpu_equalizedImage.download(img);
    cv::imwrite("test.jpg",img);

我已经检查过我使用的所有结构都已正确填充。有什么建议吗?

opencv image-processing cuda gpu
1个回答
0
投票

感谢帖子下评论的用户,我解决了问题。 显然 opencv x cuda 不会在 GPU 上连续分配图像,因此我的 cuda 内核代码计算线性化 mateniera 中的地址,但这没有用,因为 cuda 不像你在 cpu 上存储的那样存储。 解决方案是使用 XXXX 函数。完成此操作后,就可以像我一样访问了。 显然,opencv x cuda 不会在 GPU 上连续分配图像,因此我的 cuda 内核代码计算线性化 mateniera 中的地址,但这没有用,因为 cuda 不像它存储在 cpu 上那样存储。 解决方案是使用

cv::cuda::GpuMat gpu_equalizedImageSM = cv::cuda::createContinuous(gpu_resizedImage.rows,gpu_resizedImage.cols,CV_8UC1); 
功能。完成此操作后,就可以像我一样访问了。

© www.soinside.com 2019 - 2024. All rights reserved.