c++ - CUDA中图像处理的问题

标签 c++ image-processing cuda

我是 CUDA 的新手,我正在尝试用它做我的第一个项目。我正在尝试将图像数据推送到 GPU,在那里将其设为黑白并将其写入新图像。但是程序给了我一个黑色图像而不是黑白版本。我究竟做错了什么?图像的宽度和高度为 3840x2160。 Source image

Output image

__global__ void addMatrix(unsigned char *DataOut, unsigned char *DataIn)
{
    int idx = threadIdx.x;
    DataOut[idx] = (DataIn[idx] + DataIn[idx + 1] + DataIn[idx + 2]) / 3;
    //
}
int main()

{

int iWidth, iHeight, iBpp, iHeightOut, iWidthOut;

vector<unsigned char> pDataIn;
vector<unsigned char> pDataOut;


int error1 = LoadBmpFile(L"3840x2160.bmp", iWidth, iHeight, iBpp, pDataIn);

if (error1 != 0 || pDataIn.size() == 0 || iBpp != 32)
{
    std::cout << "erroror load input file!\n";
}


pDataOut.resize(pDataIn.size()/4);

unsigned int SizeIn, SizeOut;
unsigned char *devDatOut, *devDatIn, *PInData, *POutData;

int i = 0;
SizeIn = pDataIn.size();
SizeOut = pDataOut.size();
PInData = pDataIn.data();
POutData = pDataOut.data();

i = cudaMalloc((void**)&devDatIn, SizeIn * sizeof(unsigned char));
if(i != 0)
{
printf("cudaMalloc __e FAIL! Code: %d\n", i);
_getch();
}
i = cudaMalloc((void**)&devDatOut, SizeOut * sizeof(unsigned char));
if(i != cudaSuccess)
printf("cudaMalloc __e FAIL! Code: %d\n", i);

i = cudaMemcpy(devDatIn, PInData, SizeIn * sizeof(unsigned char), cudaMemcpyHostToDevice);
if(i != cudaSuccess)
printf(" cudaMemcpy __e FAIL! Code: %d\n", i);
i = cudaMemcpy(devDatOut, POutData, SizeOut * sizeof(unsigned char), cudaMemcpyHostToDevice);
if(i != cudaSuccess)
printf(" cudaMemcpy __e FAIL! Code: %d\n", i);

dim3 gridSize = dim3(1, 1, 1);   
dim3 blockSize = dim3(SizeIn, 1, 1);

addMatrix<<<gridSize, blockSize>>>(devDatIn, devDatOut);
if ( i == cudaGetLastError() )
{
printf( "Error! %d\n", cudaGetLastError() );
_getch;
}

 cudaEvent_t syncEvent;

cudaEventCreate(&syncEvent); 
cudaEventRecord(syncEvent, 0); 
 cudaEventSynchronize(syncEvent);  

 cudaMemcpy(POutData, devDatOut, SizeOut * sizeof(unsigned char), cudaMemcpyDeviceToHost);

  cudaEventDestroy(syncEvent);

i = WriteBmpFile(L"3840x2160_test2.bmp", iWidth, iHeight, 8, pDataOut.size(), pDataOut.data(), false);
    if(i != 0)
    printf(" cudaMemcpy __e FAIL! Code: %d\n", i);

    cudaFree(devDatOut);
  cudaFree(devDatIn);

}

编辑 1:

Output image after editing

最佳答案

正如在评论中看到的那样,您在每个 block 中启动了太多线程并且启动可能会失败,但是您的错误检查不完整并且您看不到它。 参见 this answer用于在启动内核后进行适当的错误检查。

顺便说一句,您必须启动几个线程较少的 block ,而不是一个包含所有这些线程的 block 。 例如,它可能是 2000 个 block ,每个 block 包含 1024 个线程。在我目前的卡片上,1024 个线程是我在每个 block 中可以拥有的最大值,因此如果我需要更多线程,我会启动多个 block ,并且通常我会启动更多 block 和更少的线程以获得更好的占用率。 您可以了解更多入住情况with this presentation .

例如,如果您总共有 10,000 个像素,则可以启动 20 个 block ,每个 block 有 500 个线程。 您可以在一个维度上为两者执行此操作:

dim3 blocks(20, 1, 1);
dim3 threads(500, 1, 1);

myKernel<<<blocks, threads>>>(...);

您的内核需要进行一些更改才能将每个特定 block 中的线程索引正确映射到内存中图片缓冲区中的唯一线性索引(在浏览器中编写,未针对您的特定项目进行测试,但线性化用一支好的旧钢笔在纸上思考就很容易理解):

__global__ void addMatrix(unsigned char *DataOut, unsigned char *DataIn)
{
    int idx = BlockIdx.x * BlockDim.x + threadIdx.x;

    unsigned char average = (unsigned char)((DataIn[idx] + DataIn[idx + 1] + DataIn[idx + 2]) / 3);

    DataOut[idx + 0] = average;
    DataOut[idx + 1] = average;
    DataOut[idx + 2] = average;
}

关于c++ - CUDA中图像处理的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36597281/

相关文章:

cuda - Nsight Eclipse : . cuda-gdbinit:没有这样的文件或目录

c++ - 如何使用模板函数和 CUDA

python - 在 Python 中从 SWIG 实例化 shared_ptr 对象

c++ - _CrtIsValidHeapPointer(block) 加载异常

c++ - 使用 std::mutex 实现信号量

ruby-on-rails - 从代码中羽化图像

Python:在极坐标图中显示笛卡尔图像

java - 制作图片拼贴和编辑(布局、背景、框架、文本、滤镜)

c++ - 如何使用 C++ 在 Linux 中获取总 CPU 使用率

c++ - 如何为项目本身、构建产品和源文件创建一个具有不同位置的简单 CLion C++ CMake 项目