[英]CS50 pset4 filter blur function
我为模糊 function 编写了一个代码,但它返回了错误的 output,原因我不知道(它对我来说看起来不错),这是一个示例(始终相同):
:( blur correctly filters middle pixel
expected "127 140 149\n", not "126 140 149\n"
:) blur correctly filters pixel on edge
:) blur correctly filters pixel in corner
:( blur correctly filters 3x3 image
expected "70 85 95\n80 9...", not "70 85 95\n80 9..."
:( blur correctly filters 4x4 image
expected "70 85 95\n80 9...", not "70 85 95\n80 9..."
代码在这里:
void blur(int height, int width, RGBTRIPLE image[height][width])
{
RGBTRIPLE original[height][width];
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
original[i][j] = image[i][j];
}
}
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
if (i == 0)
{
if (j == 0)
{
image[i][j].rgbtRed = round((original[i][j].rgbtRed + original[i + 1][j].rgbtRed + original[i][j + 1].rgbtRed + original[i + 1][j + 1].rgbtRed) / 4);
image[i][j].rgbtGreen = round((original[i][j].rgbtGreen + original[i + 1][j].rgbtGreen + original[i][j + 1].rgbtGreen + original[i + 1][j + 1].rgbtGreen) / 4);
image[i][j].rgbtBlue = round((original[i][j].rgbtBlue + original[i + 1][j].rgbtBlue + original[i][j + 1].rgbtBlue + original[i + 1][j + 1].rgbtBlue) / 4);
}
else if (j == width - 1)
{
image[i][j].rgbtRed = round((original[i][j].rgbtRed + original[i + 1][j].rgbtRed + original[i][j - 1].rgbtRed + original[i + 1][j - 1].rgbtRed) / 4);
image[i][j].rgbtGreen = round((original[i][j].rgbtGreen + original[i + 1][j].rgbtGreen + original[i][j - 1].rgbtGreen + original[i + 1][j - 1].rgbtGreen) / 4);
image[i][j].rgbtBlue = round((original[i][j].rgbtBlue + original[i + 1][j].rgbtBlue + original[i][j - 1].rgbtBlue + original[i + 1][j - 1].rgbtBlue) / 4);
}
else
{
image[i][j].rgbtRed = round((original[i][j].rgbtRed + original[i + 1][j].rgbtRed + original[i][j - 1].rgbtRed + original[i + 1][j - 1].rgbtRed + original[i][j + 1].rgbtRed + original[i + 1][j + 1].rgbtRed) / 6);
image[i][j].rgbtGreen = round((original[i][j].rgbtGreen + original[i + 1][j].rgbtGreen + original[i][j - 1].rgbtGreen + original[i + 1][j - 1].rgbtGreen + original[i][j + 1].rgbtGreen + original[i + 1][j + 1].rgbtGreen) / 6);
image[i][j].rgbtBlue = round((original[i][j].rgbtBlue + original[i + 1][j].rgbtBlue + original[i][j - 1].rgbtBlue + original[i + 1][j - 1].rgbtBlue + original[i][j + 1].rgbtBlue + original[i + 1][j + 1].rgbtBlue) / 6);
}
}
else if (i > 0 && i < height - 1)
{
if (j == 0)
{
image[i][j].rgbtRed = round((original[i][j].rgbtRed + original[i + 1][j].rgbtRed + original[i - 1][j].rgbtRed + original[i + 1][j + 1].rgbtRed + original[i][j + 1].rgbtRed + original[i - 1][j + 1].rgbtRed) / 6);
image[i][j].rgbtGreen = round((original[i][j].rgbtGreen + original[i + 1][j].rgbtGreen + original[i- 1][j].rgbtGreen + original[i + 1][j + 1].rgbtGreen + original[i][j + 1].rgbtGreen + original[i - 1][j + 1].rgbtGreen) / 6);
image[i][j].rgbtBlue = round((original[i][j].rgbtBlue + original[i + 1][j].rgbtBlue + original[i - 1][j].rgbtBlue + original[i + 1][j + 1].rgbtBlue + original[i][j + 1].rgbtBlue + original[i - 1][j + 1].rgbtBlue) / 6);
}
else if (j == width - 1)
{
image[i][j].rgbtRed = round((original[i][j].rgbtRed + original[i + 1][j].rgbtRed + original[i - 1][j].rgbtRed + original[i + 1][j - 1].rgbtRed + original[i][j - 1].rgbtRed + original[i - 1][j - 1].rgbtRed) / 6);
image[i][j].rgbtGreen = round((original[i][j].rgbtGreen + original[i + 1][j].rgbtGreen + original[i- 1][j].rgbtGreen + original[i + 1][j - 1].rgbtGreen + original[i][j - 1].rgbtGreen + original[i - 1][j - 1].rgbtGreen) / 6);
image[i][j].rgbtBlue = round((original[i][j].rgbtBlue + original[i + 1][j].rgbtBlue + original[i - 1][j].rgbtBlue + original[i + 1][j - 1].rgbtBlue + original[i][j - 1].rgbtBlue + original[i - 1][j - 1].rgbtBlue) / 6);
}
else
{
image[i][j].rgbtRed = round((original[i][j].rgbtRed + original[i][j - 1].rgbtRed + original[i][j + 1].rgbtRed + original[i + 1][j - 1].rgbtRed + original[i + 1][j + 1].rgbtRed + original[i + 1][j].rgbtRed + original[i - 1][j - 1].rgbtRed + original[i - 1][j + 1].rgbtRed + original[i - 1][j].rgbtRed) / 9);
image[i][j].rgbtGreen = round((original[i][j].rgbtGreen + original[i][j - 1].rgbtGreen + original[i][j + 1].rgbtGreen + original[i + 1][j - 1].rgbtGreen + original[i + 1][j + 1].rgbtGreen+ original[i + 1][j].rgbtGreen + original[i - 1][j - 1].rgbtGreen + original[i - 1][j + 1].rgbtGreen + original[i - 1][j].rgbtGreen) / 9);
image[i][j].rgbtBlue = round((original[i][j].rgbtBlue + original[i][j - 1].rgbtBlue + original[i][j + 1].rgbtBlue + original[i + 1][j - 1].rgbtBlue + original[i + 1][j + 1].rgbtBlue + original[i + 1][j].rgbtBlue + original[i - 1][j - 1].rgbtBlue + original[i - 1][j + 1].rgbtBlue + original[i - 1][j].rgbtBlue) / 9);
}
}
else if (i == height - 1)
{
if (j == 0)
{
image[i][j].rgbtRed = round((original[i][j].rgbtRed + original[i - 1][j].rgbtRed + original[i][j + 1].rgbtRed + original[i - 1][j + 1].rgbtRed) / 4);
image[i][j].rgbtGreen = round((original[i][j].rgbtGreen + original[i - 1][j].rgbtGreen + original[i][j + 1].rgbtGreen + original[i - 1][j + 1].rgbtGreen) / 4);
image[i][j].rgbtBlue = round((original[i][j].rgbtBlue + original[i - 1][j].rgbtBlue + original[i][j + 1].rgbtBlue + original[i - 1][j + 1].rgbtBlue) / 4);
}
else if (j == width - 1)
{
image[i][j].rgbtRed = round((original[i][j].rgbtRed + original[i - 1][j].rgbtRed + original[i][j - 1].rgbtRed + original[i - 1][j - 1].rgbtRed) / 4);
image[i][j].rgbtGreen = round((original[i][j].rgbtGreen + original[i - 1][j].rgbtGreen + original[i][j - 1].rgbtGreen + original[i - 1][j - 1].rgbtGreen) / 4);
image[i][j].rgbtBlue = round((original[i][j].rgbtBlue + original[i - 1][j].rgbtBlue + original[i][j - 1].rgbtBlue + original[i - 1][j - 1].rgbtBlue) / 4);
}
else
{
image[i][j].rgbtRed = round((original[i][j].rgbtRed + original[i - 1][j].rgbtRed + original[i][j - 1].rgbtRed + original[i - 1][j - 1].rgbtRed + original[i][j + 1].rgbtRed + original[i - 1][j + 1].rgbtRed) / 6);
image[i][j].rgbtGreen = round((original[i][j].rgbtGreen + original[i - 1][j].rgbtGreen + original[i][j - 1].rgbtGreen + original[i - 1][j - 1].rgbtGreen + original[i][j + 1].rgbtGreen + original[i - 1][j + 1].rgbtGreen) / 6);
image[i][j].rgbtBlue = round((original[i][j].rgbtBlue + original[i - 1][j].rgbtBlue + original[i][j - 1].rgbtBlue + original[i - 1][j - 1].rgbtBlue + original[i][j + 1].rgbtBlue + original[i - 1][j + 1].rgbtBlue) / 6);
}
}
}
}
}
如果结构RGBTRIPLE
的成员具有 integer 类型,则 integer 划分发生在如下行中
image[i][j].rgbtRed = round((original[i][j].rgbtRed + original[i + 1][j].rgbtRed + original[i][j + 1].rgbtRed + original[i + 1][j + 1].rgbtRed) / 4);
并且结果在传递给round()
function之前被截断为整数。
除法器应该是像4.0
这样的浮点数,而不是像4
这样的整数。
如果在应用此更改后法官仍然拒绝您的答案,则应该是由于浮点数的计算错误。 在这种情况下,您应该避免使用浮点数计算,并考虑如何仅使用整数计算来计算所需的值。
MikeCAT 的回答肯定是对的。 作为他建议的替代方案,您可以通过在 integer 除法之前添加一半除数来避免与浮点的转换,例如
image[i][j].rgbtRed = (original[i][j].rgbtRed + … + original[i+1][j+1].rgbtRed + 2) / 4;
…
image[i][j].rgbtRed = (original[i][j].rgbtRed + … + original[i-1][j ].rgbtRed + 4) / 9;
我想我的解决方案很短
void blur(int height, int width, RGBTRIPLE image[height][width])
{
for(int i = 0; i < height; i++)
{
for(int j = 0; j < width; j++)
{
int avgrgb[3] = {0,0,0}, n = 0;
int a[3][3] = { {i-1, i-1, i-1}, {i, i, i}, {i+1, i+1,i+1} }, b[3][3] = { {j-1, j, j+1}, {j-1, j, j+1}, {j-1, j, j+1} };
for(int x = 0; x < 3; x++)
{
for(int y = 0; y < 3; y++)
{
if (a[x][y] >= 0 && a[x][y] >= 0)
{
avgrgb[0] += image[a[x][y]][b[x][y]].rgbtRed;
avgrgb[1] += image[a[x][y]][b[x][y]].rgbtGreen;
avgrgb[2] += image[a[x][y]][b[x][y]].rgbtBlue;
n++;
}
}
}
avgrgb[0] /= n;
avgrgb[1] /= n;
avgrgb[2] /= n;
image[i][j].rgbtRed = avgrgb[0];
image[i][j].rgbtGreen = avgrgb[1];
image[i][j].rgbtBlue = avgrgb[2];
}
}
return;
}
您的解决方案是完美的,您只需编写 4.0, 6.0, 9.0 而不是 4,6, 9
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.