【发布时间】:2021-09-11 18:46:04
【问题描述】:
所以在这个项目中,我需要获取一个 image.bmp 文件并使用“box blur”对其进行模糊处理。
Box Blurring的说明如下:
对于这个问题,我们将使用“框模糊”,它的工作原理是获取每个像素,并且对于每个颜色值,通过平均相邻像素的颜色值给它一个新值。
(示例)每个像素的新值将是原始像素的 1 行和列内的所有像素值的平均值(形成 3x3 框)。例如,像素 6 的每个颜色值将通过平均像素 1、2、3、5、6、7、9、10 和 11 的原始颜色值来获得(请注意,像素 6 本身包含在平均的)。同样,像素 11 的颜色值将通过平均像素 6、7、8、10、11、12、14、15 和 16 的颜色值来获得。
对于沿边缘或角落的像素,例如像素 15,我们仍会查找 1 行和列内的所有像素:在本例中,为像素 10、11、12、14、15 和 16。
现在我知道我的代码有点长而且很业余,但这只是因为我是一个业余爱好者,但我在没有任何帮助的情况下走到了这一步:
void blur(int height, int width, RGBTRIPLE image[height][width])
{
// iterate through every row
for (int i = 0; i < height; i++)
{
//for every column
for (int j = 0; j < width; j++)
{
int avRed = 0;
int avGreen = 0;
int avBlue = 0;
// check if the current index is an index of an edge
if ((i == 0 && (j >= 0 && j <= width - 1))
|| ((i >= 0 && i <= height - 1) && j == 0)
|| (i == height - 1 && (j >= 0 && j <= width - 1))
|| ((i >= 0 && i <= height -1) && j == width - 1))
{
// if it is : check if it is a corner
if ((i == 0 && j == 0)
|| (i == 0 && j == width - 1)
|| (i == height - 1 && j == 0)
|| (i == height - 1 && j == width - 1))
{
if (i == 0 && j == 0)
{
avRed = round((image[i][j].rgbtRed + image[i + 1][j].rgbtRed + image[i + 1][j + 1].rgbtRed + image[i][j + 1].rgbtRed) / 4.0);
avGreen = round((image[i][j].rgbtGreen + image[i + 1][j].rgbtGreen + image[i + 1][j + 1].rgbtGreen + image[i][j + 1].rgbtGreen) / 4.0);
avBlue = round((image[i][j].rgbtBlue + image[i + 1][j].rgbtBlue + image[i + 1][j + 1].rgbtBlue + image[i][j + 1].rgbtBlue) / 4.0);
image[i][j].rgbtRed = avRed;
image[i][j].rgbtGreen = avGreen;
image[i][j].rgbtBlue = avBlue;
}
if (i == 0 && j == width - 1)
{
avRed = round((image[i][j].rgbtRed + image[i +1 ][j].rgbtRed + image[i + 1][j - 1].rgbtRed + image[i][j - 1].rgbtRed) / 4.0);
avGreen = round((image[i][j].rgbtGreen + image[i + 1][j].rgbtGreen + image[i + 1][j - 1].rgbtGreen + image[i][j - 1].rgbtGreen) / 4.0);
avBlue = round((image[i][j].rgbtBlue + image[i + 1][j].rgbtBlue + image[i + 1][j - 1].rgbtBlue + image[i][j - 1].rgbtBlue) / 4.0);
image[i][j].rgbtRed = avRed;
image[i][j].rgbtGreen = avGreen;
image[i][j].rgbtBlue = avBlue;
}
if(i == height - 1 && j == 0)
{
avRed = round((image[i][j].rgbtRed + image[i - 1][j].rgbtRed + image[i - 1][j + 1].rgbtRed + image[i][j + 1].rgbtRed) / 4.0);
avGreen= round((image[i][j].rgbtGreen + image[i - 1][j].rgbtGreen + image[i - 1][j + 1].rgbtGreen + image[i][j + 1].rgbtGreen) / 4.0);
avRed = round((image[i][j].rgbtBlue + image[i - 1][j].rgbtBlue + image[i - 1][j + 1].rgbtBlue + image[i][j + 1].rgbtBlue) / 4.0);
image[i][j].rgbtRed = avRed;
image[i][j].rgbtGreen = avGreen;
image[i][j].rgbtBlue = avBlue;
}
if (i == height - 1 && j == width - 1)
{
avRed = round((image[i][j].rgbtRed + image[i - 1][j].rgbtRed + image[i - 1][j - 1].rgbtRed + image[i][j - 1].rgbtRed) / 4.0);
avGreen = round((image[i][j].rgbtGreen + image[i - 1][j].rgbtGreen + image[i - 1][j - 1].rgbtGreen + image[i][j - 1].rgbtGreen) / 4.0);
avBlue = round((image[i][j].rgbtBlue + image[i - 1][j].rgbtBlue + image[i - 1][j - 1].rgbtBlue + image[i][j - 1].rgbtBlue) / 4.0);
image[i][j].rgbtRed = avRed;
image[i][j].rgbtGreen = avGreen;
image[i][j].rgbtBlue = avBlue;
}
}
else // if it is not a corner index
{
if (i == 0 && (j >= 1 && j <= width - 2))
{
avRed = round((image[i][j].rgbtRed + image[i][j - 1].rgbtRed + image[i][j + 1].rgbtRed + image[i + 1][j].rgbtRed + image[i + 1][j - 1].rgbtRed + image[i + 1][j + 1].rgbtRed) / 6.0);
avGreen = round((image[i][j].rgbtGreen + image[i][j - 1].rgbtGreen + image[i][j + 1].rgbtGreen + image[i + 1][j].rgbtGreen + image[i + 1][j - 1].rgbtGreen + image[i + 1][j + 1].rgbtGreen) / 6.0);
avBlue = round((image[i][j].rgbtBlue + image[i][j - 1].rgbtBlue + image[i][j + 1].rgbtBlue + image[i + 1][j].rgbtBlue + image[i + 1][j - 1].rgbtBlue + image[i + 1][j + 1].rgbtBlue) / 6.0);
image[i][j].rgbtRed = avRed;
image[i][j].rgbtGreen = avGreen;
image[i][j].rgbtBlue = avBlue;
}
if ((i >= 1 && i <= height - 2) && j == 0)
{
avRed = round((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) / 6.0);
avGreen = round((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) / 6.0);
avBlue = round((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) / 6.0);
image[i][j].rgbtRed = avRed;
image[i][j].rgbtGreen = avGreen;
image[i][j].rgbtBlue = avBlue;
}
if (i == height - 1 && (j >= 1 && j <= width - 2))
{
avRed = round((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) / 6.0);
avGreen = round((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) / 6.0);
avBlue = round((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) / 6.0);
image[i][j].rgbtRed = avRed;
image[i][j].rgbtGreen = avGreen;
image[i][j].rgbtBlue = avBlue;
}
if ((i >= 1 && i <= height -2) && j == width - 1)
{
avRed = round((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) / 6.0);
avGreen = round((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) / 6.0);
avBlue = round((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) / 6.0);
image[i][j].rgbtRed = avRed;
image[i][j].rgbtGreen = avGreen;
image[i][j].rgbtBlue = avBlue;
}
}
}
else // if it is not an index of an edge at all
{
avRed = round(((image[i - 1][j - 1].rgbtRed) + (image[i - 1][j].rgbtRed) + (image[i - 1][j + 1].rgbtRed) + (image[i][j - 1].rgbtRed) + (image[i][j].rgbtRed) + (image[i][j + 1].rgbtRed) + (image[i + 1][j - 1].rgbtRed) + (image[i + 1][j].rgbtRed) + (image[i + 1][j + 1].rgbtRed)) / 9.0);
avGreen = round(((image[i - 1][j - 1].rgbtGreen) + (image[i - 1][j].rgbtGreen) + (image[i - 1][j + 1].rgbtGreen) + (image[i][j - 1].rgbtGreen) + (image[i][j].rgbtGreen) + (image[i][j + 1].rgbtGreen) + (image[i + 1][j - 1].rgbtGreen) + (image[i + 1][j].rgbtGreen) + (image[i + 1][j + 1].rgbtGreen)) / 9.0);
avBlue = round(((image[i - 1][j - 1].rgbtBlue) + (image[i - 1][j].rgbtBlue) + (image[i - 1][j + 1].rgbtBlue) + (image[i][j - 1].rgbtBlue) + (image[i][j].rgbtBlue) + (image[i][j + 1].rgbtBlue) + (image[i + 1][j - 1].rgbtBlue) + (image[i + 1][j].rgbtBlue) + (image[i + 1][j + 1].rgbtBlue)) / 9.0);
image[i][j].rgbtRed = avRed;
image[i][j].rgbtGreen = avGreen;
image[i][j].rgbtBlue = avBlue;
}
}
}
return;
}
现在,程序在某种程度上模糊了图像,但没有达到正确的程度。当我通过 cs50 的预设测试用例对其进行测试时,我的 RGB 比率对于 corner 索引是正确的,但对于所有其他索引都是正确的。为什么会发生这种情况?
【问题讨论】:
-
您必须制作一个新图像,然后将其复制到原件上。否则,您将从已经平均的一些像素中进行平均。
-
@WeatherVane 谢谢,我现在清楚地看到了问题。
-
风格建议:当你反复引用
image[i][j]之类的东西时,给它一个有意义的名字。像RGBTRIPLE pixel = image[i][j];这样的东西。这将使代码更容易使用。 -
@Chris 感谢您的建议和编辑。作为初学者,非常感谢任何帮助。
-
不客气。通常,如果您发现自己使用复制和粘贴,可能会有更好的方法。此外,如果您连续有多个
ifs 都是独占的,您可能忘记了一些elses。