使用C ++ / CUDA和CImg将交错数据的图像数组转换为非交错数据时出现问题

时间:2019-01-04 23:08:58

标签: c++ image cuda cimg

我正在尝试使用CUDA将RGBRGB值数组转换为RRGGBB值数组。我现在拥有的代码是:

__global__ void convertToo(UCHAR *imageData, UCHAR *outData, size_t dataSize)
{
    size_t i = threadIdx.x + blockIdx.x * blockDim.x;
    if (i >= dataSize) return;
    auto index = ((i % 3) * (dataSize / 3)) + i;
    if (index >= dataSize) return;
    auto iVal = imageData[i];
    outData[index] = iVal;
}

(索引和Ival用于调试) 调用它的代码是:

auto blockSize = size / 1024;
convertToo <<<blockSize, 1024>> > (imageData, outData, size * sizeof(UCHAR));

其中imageData是包含RGB值的数组,而outData是新格式化的数据应该存放的位置。

CImg<unsigned char> image(s.c_str());
CImg<unsigned char> result(s.c_str());

size_t old_sizeX = image.width();
size_t old_sizeY = image.height();
size_t old_spectrum = image.spectrum();
size_t old_depth = image.depth();
size_t size = image.size();
image.permute_axes("cxyz");

UCHAR *imageData, *outData;
gpuErrchk(cudaMalloc(&imageData, sizeof(UCHAR) * size));
gpuErrchk(cudaMalloc(&outData, sizeof(UCHAR) * size));
gpuErrchk(cudaDeviceSynchronize());


unsigned char *data = image.data();

gpuErrchk(cudaMemcpy(imageData, data, sizeof(UCHAR) * size, cudaMemcpyHostToDevice));
gpuErrchk(cudaDeviceSynchronize());

auto blockSize = size / 1024;
convertToo <<<blockSize, 1024>> > (imageData, outData, size * sizeof(UCHAR));
gpuErrchk(cudaDeviceSynchronize());
gpuErrchk(cudaPeekAtLastError());

gpuErrchk(cudaMemcpy(result.data(), outData, size * sizeof(UCHAR), cudaMemcpyDeviceToHost));

image.permute_axes("yzcx");

CImgDisplay main_disp(image, "Original image");
CImgDisplay main_disp2(result, "Blurred image");
while (1)
{
    main_disp.wait();
    main_disp2.wait();
}
std::cout << "Done" << std::endl;

我得到的问题是,当我将图像放回原处时,我没有得到逻辑上应该得到的相同结果(使用CImg)。我尝试查看每个阵列并查看它们是否正确,但是似乎没有发现问题。

1 个答案:

答案 0 :(得分:1)

您对index的计算是错误的。让我们分解一下。

首先要弄清楚您拥有哪种颜色成分(i % 3),然后将其调整为该颜色的正确“页面”(* (datasize / 3))。最后,为像素(i)添加偏移量。

这最后一部分是错误的。由于每个像素为3个字节,因此您需要将i除以3以获得正确的偏移量:

auto index = ((i % 3) * (dataSize / 3)) + i / 3;