我对CS50
的过滤器分配中的功能
blur
有问题。
我一直被同样的错误消息困扰,想知道是否有人可以帮助指出我错过了什么。
目前,代码确实模糊了图像,但代码通过的唯一检查是关于角像素的,按照这个逻辑,我发现很难理解为什么边缘和中间像素不起作用。
我对编程非常陌生,所以请原谅重复的代码,我确信有更好的方法来解决这个问题,但我首先想看看我是否可以让这个方法在进行了如此深入的研究后通过检查。
// Blur image
void blur(int height, int width, RGBTRIPLE image[height][width])
{
RGBTRIPLE copy[height][width];
float count = 0;
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
copy[i][j] = image[i][j];
// check that the + 1's and - 1's won't take loop out of bounds
// left bottom corner (/4)
if (i + 1 == height && j - 1 < 0)
{
count = 4.0;
// red
copy[i][j].rgbtRed = (image[i][j].rgbtRed + image[i - 1][j].rgbtRed +
image[i][j + 1].rgbtRed + image[i - 1][j + 1].rgbtRed) / count;
// green
copy[i][j].rgbtGreen = (image[i][j].rgbtGreen + image[i - 1][j].rgbtGreen +
image[i][j + 1].rgbtGreen + image[i - 1][j + 1].rgbtGreen) / count;
// blue
copy[i][j].rgbtBlue = (image[i][j].rgbtBlue + image[i - 1][j].rgbtBlue +
image[i][j + 1].rgbtBlue + image[i - 1][j + 1].rgbtBlue) / count;
}
// right top corner
else if (i - 1 < 0 && j + 1 == width)
{
count = 4.0;
// red
copy[i][j].rgbtRed = (image[i][j].rgbtRed + image[i + 1][j].rgbtRed +
image[i][j - 1].rgbtRed + image[i + 1][j - 1].rgbtRed) / count;
// green
copy[i][j].rgbtGreen = (image[i][j].rgbtGreen + image[i + 1][j].rgbtGreen +
image[i][j - 1].rgbtGreen + image[i + 1][j - 1].rgbtGreen) / count;
// blue
copy[i][j].rgbtBlue = (image[i][j].rgbtBlue + image[i + 1][j].rgbtBlue +
image[i][j - 1].rgbtBlue + image[i + 1][j - 1].rgbtBlue) / count;
}
// right bottom corner
else if (i + 1 == height && j + 1 == width)
{
count = 4.0;
// red
copy[i][j].rgbtRed = (image[i][j].rgbtRed + image[i - 1][j].rgbtRed +
image[i][j - 1].rgbtRed + image[i - 1][j - 1].rgbtRed) /
count;
// green
copy[i][j].rgbtGreen = (image[i][j].rgbtGreen + image[i - 1][j].rgbtGreen +
image[i][j - 1].rgbtGreen + image[i - 1][j - 1].rgbtGreen) / c
ount;
// blue
copy[i][j].rgbtBlue = (image[i][j].rgbtBlue + image[i - 1][j].rgbtBlue +
image[i][j - 1].rgbtBlue + image[i - 1][j - 1].rgbtBlue) /
count;
}
// left top corner
else if (i - 1 < 0 && j - 1 < 0)
{
count = 4.0;
// red
copy[i][j].rgbtRed = (image[i][j].rgbtRed + image[i + 1][j].rgbtRed +
image[i][j + 1].rgbtRed + image[i + 1][j + 1].rgbtRed) /
count;
// green
copy[i][j].rgbtGreen = (image[i][j].rgbtGreen + image[i + 1][j].rgbtGreen +
image[i][j + 1].rgbtGreen + image[i + 1][j + 1].rgbtGreen) /
count;
// blue
copy[i][j].rgbtBlue = (image[i][j].rgbtBlue + image[i + 1][j].rgbtBlue +
image[i][j + 1].rgbtBlue + image[i + 1][j + 1].rgbtBlue) /
count;
}
// left edge (/6)
else if (j - 1 < 0)
{
count = 6.0;
// red
copy[i][j].rgbtRed = (image[i][j].rgbtRed + image[i + 1][j].rgbtRed +
image[i - 1][j].rgbtRed + image[i][j + 1].rgbtRed +
image[i + 1][j + 1].rgbtRed + image[i - 1][j + 1].rgbtRed) /
count;
// green
copy[i][j].rgbtGreen = (image[i][j].rgbtGreen + image[i + 1][j].rgbtGreen +
image[i - 1][j].rgbtGreen +
image[i][j + 1].rgbtGreen + image[i + 1][j + 1].rgbtGreen +
image[i - 1][j + 1].rgbtGreen) / count;
// blue
copy[i][j].rgbtBlue = (image[i][j].rgbtBlue + image[i + 1][j].rgbtBlue +
image[i - 1][j].rgbtBlue + image[i][j + 1].rgbtBlue +
image[i + 1][j + 1].rgbtBlue + image[i - 1][j + 1].rgbtBlue) /
count;
}
// right edge
else if (j + 1 == width)
{
count = 6.0;
// red
copy[i][j].rgbtRed = (image[i][j].rgbtRed + image[i + 1][j].rgbtRed +
image[i - 1][j].rgbtRed + image[i][j - 1].rgbtRed +
image[i + 1][j - 1].rgbtRed + image[i - 1][j - 1].rgbtRed) /
count;
// green
copy[i][j].rgbtGreen = (image[i][j].rgbtGreen + image[i + 1][j].rgbtGreen +
image[i - 1][j].rgbtGreen + image[i][j - 1].rgbtGreen +
image[i + 1][j - 1].rgbtGreen + image[i - 1][j - 1].rgbtGreen) /
count;
// blue
copy[i][j].rgbtBlue = (image[i][j].rgbtBlue + image[i + 1][j].rgbtBlue +
image[i - 1][j].rgbtBlue + image[i][j - 1].rgbtBlue +
image[i + 1][j - 1].rgbtBlue + image[i - 1][j - 1].rgbtBlue) /
count;
}
// top edge
else if (i - 1 < 0)
{
count = 6.0;
// red
copy[i][j].rgbtRed = (image[i][j].rgbtRed + image[i + 1][j].rgbtRed +
image[i][j + 1].rgbtRed + image[i][j - 1].rgbtRed +
image[i + 1][j + 1].rgbtRed + image[i + 1][j - 1].rgbtRed) /
count;
// green
copy[i][j].rgbtGreen = (image[i][j].rgbtGreen + image[i + 1][j].rgbtGreen +
image[i][j + 1].rgbtGreen + image[i][j - 1].rgbtGreen +
image[i + 1][j + 1].rgbtGreen + image[i + 1][j - 1].rgbtGreen) /
count;
// blue
copy[i][j].rgbtBlue = (image[i][j].rgbtBlue + image[i + 1][j].rgbtBlue +
image[i][j + 1].rgbtBlue + image[i][j - 1].rgbtBlue +
image[i + 1][j + 1].rgbtBlue + image[i + 1][j - 1].rgbtBlue) /
count;
}
// bottom edge
else if (i + 1 == height)
{
count = 6.0;
// red
copy[i][j].rgbtRed = (image[i][j].rgbtRed + image[i - 1][j].rgbtRed +
image[i][j + 1].rgbtRed + image[i][j - 1].rgbtRed +
image[i - 1][j + 1].rgbtRed + image[i - 1][j - 1].rgbtRed) /
count;
// green
copy[i][j].rgbtGreen = (image[i][j].rgbtGreen + image[i - 1][j].rgbtGreen +
image[i][j + 1].rgbtGreen + image[i][j - 1].rgbtGreen +
image[i - 1][j + 1].rgbtGreen + image[i - 1][j - 1].rgbtGreen) /
count;
// blue
copy[i][j].rgbtBlue = (image[i][j].rgbtBlue + image[i - 1][j].rgbtBlue +
image[i][j + 1].rgbtBlue + image[i][j - 1].rgbtBlue +
image[i - 1][j + 1].rgbtBlue + image[i - 1][j - 1].rgbtBlue) /
count;
}
else
{
count = 9.0;
// red
copy[i][j].rgbtRed =
(image[i][j].rgbtRed + image[i + 1][j].rgbtRed + image[i - 1][j].rgbtRed +
image[i][j + 1].rgbtRed + image[i][j - 1].rgbtRed + image[i + 1][j + 1].rgbtRed +
image[i + 1][j - 1].rgbtRed + image[i - 1][j + 1].rgbtRed +
image[i - 1][j - 1].rgbtRed) / count;
// green
copy[i][j].rgbtGreen =
(image[i][j].rgbtGreen + image[i + 1][j].rgbtGreen + image[i - 1][j].rgbtGreen +
image[i][j + 1].rgbtGreen + image[i][j - 1].rgbtGreen +
image[i + 1][j + 1].rgbtGreen + image[i + 1][j - 1].rgbtGreen +
image[i - 1][j + 1].rgbtGreen + image[i - 1][j - 1].rgbtGreen) / count;
// blue
copy[i][j].rgbtBlue =
(image[i][j].rgbtBlue + image[i + 1][j].rgbtBlue + image[i - 1][j].rgbtBlue +
image[i][j + 1].rgbtBlue + image[i][j - 1].rgbtBlue +
image[i + 1][j + 1].rgbtBlue + image[i + 1][j - 1].rgbtBlue +
image[i - 1][j + 1].rgbtBlue + image[i - 1][j - 1].rgbtBlue) / count;
}
image[i][j].rgbtRed = round(copy[i][j].rgbtRed);
image[i][j].rgbtGreen = round(copy[i][j].rgbtGreen);
image[i][j].rgbtBlue = round(copy[i][j].rgbtBlue);
}
}
return;
}
检查50条错误消息:
:( blur correctly filters middle pixel
expected "127 140 149\n", not "145 160 169\n"
:( blur correctly filters pixel on edge
expected "80 95 105\n", not "90 106 116\n"
:) blur correctly filters pixel in corner
:( blur correctly filters 3x3 image
expected "70 85 95\n80 9...", not "70 85 95\n90 1..."
:( blur correctly filters 4x4 image
expected "70 85 95\n80 9...", not "70 85 95\n90 1..."
作业包含以下提示:
在实现
函数时,您可能会发现模糊一个像素最终会影响另一个像素的模糊。最好通过使用类似blur
的代码声明一个新的二维数组来创建image
的副本。然后将RGBTRIPLE copy[height][width];
复制到image
中,逐个像素,使用嵌套 for 循环,如下所示:copy
[代码省略]
如果您遵循此提示,则应在处理任何像素之前完成此复制操作。
或者,您可以将结果写入单独的数组,而不是遵循此提示,当您完成所有像素后,您可以将这些结果复制回
image
。
但是,您似乎没有做上述任何事情。相反,您可以执行以下操作:
copy
,然后将该值写回image
。如上所述,如果您首先将所有结果写入 copy
,然后将这些结果复制到 image
,这将是一个可行的解决方案(尽管在这种情况下,您可能应该将数组从 copy
重命名为 results
) ,因为 copy
是一个误导性的名称)。然而,这不是你正在做的事情。相反,您会立即将结果写入image
,这将影响其他像素的模糊计算。这是错误的,因为您必须使用原始像素数据来计算所有像素的模糊。另一个问题是,对整数调用
round
没有意义。在将结果转换为整数之前,您应该调用 round
。