[英]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.