CUDA浮点给出不同的结果

时间:2013-05-12 12:06:47

标签: image cuda grayscale

我正在使用CUDA 5 / VC 2008将图像从彩色转换为灰度。

CUDA内核是:

__global__ static void rgba_to_grayscale( const uchar4* const rgbaImage, unsigned char * const greyImage,
                                     int numRows, int numCols) 
{
    int pos = blockIdx.x * blockDim.x + threadIdx.x;
    if (pos < numRows * numCols) {
        uchar4 zz = rgbaImage[pos];
        float out = 0.299f * zz.x + 0.587f * zz.y + 0.114f * zz.z;
        greyImage[pos] = (unsigned char) out;
    }

}

C ++功能是:

inline unsigned char rgba_to_grayscale( uchar4 rgbaImage) 
{
    return (unsigned char) 0.299f * rgbaImage.x + 0.587f * rgbaImage.y + 0.114f * rgbaImage.z;
}

他们都被恰当地称呼。然而,它们产生了不同的结果。

原始图片:

This colour image

CUDA版本:

cuda result

串行CPU版本:

Serial Code result

有人可以解释为什么结果不同吗?

2 个答案:

答案 0 :(得分:8)

您的CUDA功能没有问题。 CPU版本不正确。您将值0.299f * rgbaImage.x类型转换为unsigned char,这等同于以下代码:

inline unsigned char rgba_to_grayscale( uchar4 rgbaImage) 
{
    return ((unsigned char) 0.299f * rgbaImage.x) + 0.587f * rgbaImage.y + 0.114f * rgbaImage.z;
}

您必须将最终结果投射到unsigned char,如下所示:

inline unsigned char rgba_to_grayscale( uchar4 rgbaImage) 
{
    return (unsigned char) (0.299f * rgbaImage.x + 0.587f * rgbaImage.y + 0.114f * rgbaImage.z);
}

答案 1 :(得分:0)

@ sga91几乎就在那里....但是看起来字节顺序也不同了。

inline unsigned char rgba_to_grayscale( uchar4 rgbaImage) 
{
    return (unsigned char) (0.299f * rgbaImage.z + 0.587f * rgbaImage.y + 0.114f * rgbaImage.y);
}

请注意x和z是转置....

我记得以前读过这篇文章,但我现在找不到参考资料......