CS50 pset4 - 过滤器(不太舒服),棕褐色功能
CS50 pset4 - filter (less comfortable), sepia function
我为过滤器 pset 的棕褐色功能编写了代码。代码编译没有任何错误,但输出图像不完全是棕褐色。但是,在我以不同的方式编写代码后,它工作正常。有人可以解释为什么会这样吗?
第一个代码:
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;
}
第一个代码输出图像:
第二个代码:
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;
}
第二次代码输出:
两个版本的区别在于计算新像素值的类型
在第一个版本中,类型是 RGBTRIPLE
的组成成员 - 我假设它是一个无符号的 8 位整数。
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;
我为过滤器 pset 的棕褐色功能编写了代码。代码编译没有任何错误,但输出图像不完全是棕褐色。但是,在我以不同的方式编写代码后,它工作正常。有人可以解释为什么会这样吗?
第一个代码:
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;
}
第一个代码输出图像:
第二个代码:
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;
}
第二次代码输出:
两个版本的区别在于计算新像素值的类型
在第一个版本中,类型是 RGBTRIPLE
的组成成员 - 我假设它是一个无符号的 8 位整数。
pixel.rgbtBlue = round(0.272 * pix.rgbtRed + 0.534 * pix.rgbtGreen + 0.131 * pix.rgbtBlue);
在这一行(以及绿色和红色像素的等效项)中,
该值可以超过 255
,然后在分配给 pixel.rgbtBlue
.
以下钳位饱和:
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;