我正在尝试使用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)。我尝试查看每个阵列并查看它们是否正确,但是似乎没有发现问题。
答案 0 :(得分:1)
您对index
的计算是错误的。让我们分解一下。
首先要弄清楚您拥有哪种颜色成分(i % 3
),然后将其调整为该颜色的正确“页面”(* (datasize / 3)
)。最后,为像素(i
)添加偏移量。
这最后一部分是错误的。由于每个像素为3个字节,因此您需要将i
除以3以获得正确的偏移量:
auto index = ((i % 3) * (dataSize / 3)) + i / 3;