我正在编写一个程序来将rgba图像转换为灰度图像。我在这方面做了很多工作并正确实现了内核。但是,网格大小可能是错误的,即使它的逻辑是正确的。
内核:
__global__
void rgba_to_greyscale(const uchar4* const rgbaImage,
unsigned char* const greyImage,
int numRows, int numCols)
{
int x = (blockIdx.x * blockDim.x) + threadIdx.x;
int y = (blockIdx.y * blockDim.y) + threadIdx.y;
if(x >= numCols || y >= numRows)
return;
uchar4 rgba = rgbaImage[x+y];
float channelSum = 0.299f*rgba.x + 0.587f*rgba.y + 0.114f*rgba.z;
greyImage[x+y] = channelSum;
}
和内核启动:
const dim3 blockSize(10, 10, 1); //TODO
size_t gridSizeX, gridSizeY;
gridSizeX = numCols + (10 - (numCols % 10) ); //adding some number to make it multiple of 10
gridSizeY = numRows + (10 - (numRows % 10) ); //adding some number to make it multiple of 10
const dim3 gridSize( gridSizeX, gridSizeY, 1); //TODO
rgba_to_greyscale<<<gridSize, blockSize>>>(d_rgbaImage, d_greyImage, numRows, numCols);
我创建了更多的线程,然后在内核中应用绑定检查。
答案 0 :(得分:4)
您正在使用x+y
访问您的图片。但考虑到这一点,您可以通过这种方式获得的最大图像大小为numRows+numCols
。你不能只是添加这两个坐标,因为这意味着,例如(1,2)
与(3,0)
相同的图像元素是纯粹的垃圾。相反,对于每个y坐标,您必须跳过图像的整行,因此它应该是rgbaImage[x+y*numCols]
(当然,greyImage
也是如此)。但请注意,根据图像数据的布局,它可能也是另一种方式(x*numRows+y
),但我假设这里通常的图像布局(并且在你的内核中无论如何都无关紧要,因为所有像素都被平等对待。)