繁体   English   中英

CS50 pset4 - 过滤器(不太舒适),棕褐色 function

[英]CS50 pset4 - filter (less comfortable), sepia function

我为过滤器 pset 的棕褐色 function 编写了代码。 代码编译没有任何错误,但 output 图像并不完全是棕褐色。 但是,在我以不同的方式编写代码后,它工作正常。 有人可以解释为什么会这样吗?

第一个代码:

void sepia(int height, int width, RGBTRIPLE image[height][width])
{

    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            RGBTRIPLE pixel={0,0,0};
            RGBTRIPLE pix = image[i][j];

            pixel.rgbtBlue = round(0.272 * pix.rgbtRed + 0.534 * pix.rgbtGreen + 0.131 * pix.rgbtBlue);
            pixel.rgbtGreen = round(0.349 * pix.rgbtRed + 0.686 * pix.rgbtGreen + 0.168 * pix.rgbtBlue);
            pixel.rgbtRed = round(0.393 * pix.rgbtRed + 0.769 * pix.rgbtGreen + 0.189 * pix.rgbtBlue);

            if(pixel.rgbtBlue > 255)
            {
                pixel.rgbtBlue = 255;
            }
             if(pixel.rgbtGreen > 255)
            {
                pixel.rgbtGreen = 255;
            }

             if(pixel.rgbtRed > 255)
            {
                pixel.rgbtRed = 255;
            }

            image[i][j] = pixel;

        }
    }
    return;
}

第一个代码 output 图片:

第一个代码输出图像

第二个代码:

void sepia(int height, int width, RGBTRIPLE image[height][width])
{

    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            int red = image[i][j].rgbtRed;
            int green = image[i][j].rgbtGreen;
            int blue = image[i][j].rgbtBlue;

            //calculate sepia values
            int sepiaRed = round(.393 * red + .769 * green + .189 * blue);
            if(sepiaRed > 255)
            {
                sepiaRed = 255;
            }

            int sepiaGreen = round(.349 * red + .686 * green + .168 * blue);
            if(sepiaGreen > 255)
            {
                sepiaGreen = 255;
            }

            int sepiaBlue = round(.272 * red + .534 * green + .131 * blue);
            if(sepiaBlue > 255)
            {
                sepiaBlue = 255;
            }

            image[i][j].rgbtRed  = sepiaRed;
            image[i][j].rgbtGreen = sepiaGreen;
            image[i][j].rgbtBlue = sepiaBlue;


        }
    }
    return;
}

第二个代码 output:

第二个代码输出图像

两个版本之间的区别在于您计算新像素值的类型

在第一个版本中,类型是RGBTRIPLE的组成成员是什么——我假设它是一个无符号的 8 位 integer。

 pixel.rgbtBlue = round(0.272 * pix.rgbtRed + 0.534 * pix.rgbtGreen + 0.131 * pix.rgbtBlue);

在这一行(以及绿色和红色像素的等效项)中,该值可以超过255 ,然后在分配给pixel.rgbtBlue时通过分配给 8 位无符号整数来截断该值。

以下钳位饱和:

    if(pixel.rgbtBlue > 255)
    {
        pixel.rgbtBlue = 255;
    }

将始终执行 false,因为pixel.rgbtBlue不能保存大于255的值。

在代码的第二个版本中,使用了一个更大的int ,并且不会发生截断,从而允许 clamp-to-255 正常工作。

正如上面的人已经评论的那样,第一个在 if 条件下有一个被截断的值,因为 avarage 操作导致一个大于 255 的数字......这就是过滤器不能正常工作的原因。 我会考虑在第二个上少用“if/else”,也许使用“ Ternary Operator ”,以获得更清晰的代码:

        image[i][j].rgbtGreen = (sepiaGreen > 255) ? 255 : sepiaGreen;
        image[i][j].rgbtRed = (sepiaRed > 255) ? 255 : sepiaRed;
        image[i][j].rgbtBlue = (sepiaBlue > 255) ? 255 : sepiaBlue;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM