输出图像未转换为棕褐色。我的棕褐色代码有什么问题?

The output image is not converted to sepia. What is wrong with my sepia code?

我实在找不到我这里的代码有什么问题。输出图像甚至根本没有转换为棕褐色;它有点像灰度,有粉红色的天空。我应用的算法是正确的,我确实使用了 math.h 中实现的 round 函数。我想我的 if-else 语句可能有问题?

void sepia(int height, int width, RGBTRIPLE image[height][width])
{
    //process pixels by row
    for (int i = 0; i < height; i++)
    {
        //process a single pixel in a row
        for(int j = 0; j < width; j++)
        {
           //implement the algorithm
           float sepiaRed = 0.393 * image[i][j].rgbtRed + 0.769 * image[i][j].rgbtGreen + 0.189 * image[i][j].rgbtBlue;
        
            //round sepiaRed
            image[i][j].rgbtRed = round(sepiaRed);
            if (image[i][j].rgbtRed > 255)
            {
               image[i][j].rgbtRed = 255;
            }
            else
            {
               image[i][j].rgbtRed = image[i][j].rgbtRed;
            }
        
            float sepiaGreen = 0.349 * image[i][j].rgbtRed + 0.686 * image[i][j].rgbtGreen + 0.168 * image[i][j].rgbtBlue;
        
            //round sepiaGreen
            image[i][j].rgbtGreen = round(sepiaGreen);
            if (image[i][j].rgbtGreen > 255)
            {
                image[i][j].rgbtGreen = 255;
            }
            else
            {
                image[i][j].rgbtGreen = image[i][j].rgbtGreen;
            }
        
            float sepiaBlue = 0.272 * image[i][j].rgbtRed + 0.534 * image[i][j].rgbtGreen + 0.131 * image[i][j].rgbtBlue;
            //round sepiaBlue
            image[i][j].rgbtBlue = round(sepiaBlue);
            if (image[i][j].rgbtBlue > 255)
            {
                image[i][j].rgbtBlue = 255;
            }
            else
            {
               image[i][j].rgbtBlue = image[i][j].rgbtBlue;
            }
       }
    }
    return;
}

问题在这里: image[i][j].rgbtRed = round(sepiaRed); 我假设 rgbtRed 是 8 位长无符号整数(通常称为“字节”)。因此,此操作将只留下 sepiaRed 的四舍五入部分的最低 8 位。其余位将在转换为 8 位整数期间被截断。

稍后的检查如:

if (image[i][j].rgbtGreen > 255)

没有意义,因为 8 位无符号整数可以表示 0-255 范围内的数字。它不可能大于 255。

此外,下面这行看起来很多余:

image[i][j].rgbtRed = image[i][j].rgbtRed;

正确的解决方案应该对 float 值和下一轮应用限制并存储为 8 位整数。

if (sepiaGreen > 255)
  sepiaGreen = 255;
image[i][j].rgbtGreen = round(sepiaGreen);

另一个问题。 在 更新 image[i][j] 之前计算所有棕褐色组件 。 否则 sepiaRed 将在计算 sepiaGreen 时用作 rgbtRed


内部循环主体的最终代码可以是:

// extract color component for give pixel
float r = image[i][j].rgbtRed;
float g = image[i][j].rgbtGreen;
float b = image[i][j].rgbtBlue;

// compute sepia components
float sepiaRed   = 0.393 * r + 0.769 * g + 0.189 * b;
float sepiaGreen = 0.349 * r + 0.686 * g + 0.168 * b;
float sepiaBlue  = 0.272 * r + 0.534 * g + 0.131 * b;

// truncate to 0-255
if (sepiaRed   > 255) sepiaRed   = 255;
if (sepiaGreen > 255) sepiaGreen = 255;
if (sepiaBlue  > 255) sepiaBlue  = 255;

// round and store
image[i][j].rgbtRed   = round(sepiaRed);
image[i][j].rgbtGreen = round(sepiaGreen);
image[i][j].rgbtBlue  = round(sepiaBlue);