【问题标题】:Blurring an image.bmp with "box blur" technique in C在 C 中使用“框模糊”技术模糊 image.bmp
【发布时间】: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。

标签: c cs50


【解决方案1】:

首先使用 forloop 将原始图像的像素逐个像素地复制到另一个类型为 RGBTRIPLE 的变量中,如果不是第一个模糊像素会影响下一个要模糊的像素,那么你算算。

这对我有用!

    // Blur image
void blur(int height, int width, RGBTRIPLE image[height][width])
{
    RGBTRIPLE copy[height][width];
    for (int i = 0; i < width; i++)
    {
        for (int j = 0; j < height; j++)
        {
            copy[i][j] = image[i][j];
        }
    }
    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            // check for 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))
            {
                //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)
                    {
                        image[i][j].rgbtRed = (int) round((copy[i][j].rgbtRed + copy[i + 1][j].rgbtRed + copy[i + 1][j + 1].rgbtRed + copy[i][j + 1].rgbtRed) / 4.0);
                        image[i][j].rgbtGreen = (int) round((copy[i][j].rgbtGreen + copy[i + 1][j].rgbtGreen + copy[i + 1][j + 1].rgbtGreen + copy[i][j + 1].rgbtGreen) / 4.0);
                        image[i][j].rgbtBlue = (int) round((copy[i][j].rgbtBlue + copy[i + 1][j].rgbtBlue + copy[i + 1][j + 1].rgbtBlue + copy[i][j + 1].rgbtBlue) / 4.0);
                    }

                    if (i == 0 && j == width - 1)
                    {
                        image[i][j].rgbtRed = (int) round((copy[i][j].rgbtRed + copy[i +1 ][j].rgbtRed + copy[i + 1][j - 1].rgbtRed + copy[i][j - 1].rgbtRed) / 4.0);
                        image[i][j].rgbtGreen = (int) round((copy[i][j].rgbtGreen + copy[i + 1][j].rgbtGreen + copy[i + 1][j - 1].rgbtGreen + copy[i][j - 1].rgbtGreen) / 4.0);
                        image[i][j].rgbtBlue = (int) round((copy[i][j].rgbtBlue + copy[i + 1][j].rgbtBlue + copy[i + 1][j - 1].rgbtBlue + copy[i][j - 1].rgbtBlue) / 4.0);
                    }

                    if (i == height - 1 && j == 0)
                    {
                        image[i][j].rgbtRed = (int) round((copy[i][j].rgbtRed + copy[i - 1][j].rgbtRed + copy[i - 1][j + 1].rgbtRed + copy[i][j + 1].rgbtRed) / 4.0);
                        image[i][j].rgbtGreen = (int) round((copy[i][j].rgbtGreen + copy[i - 1][j].rgbtGreen + copy[i - 1][j + 1].rgbtGreen + copy[i][j + 1].rgbtGreen) / 4.0);
                        image[i][j].rgbtBlue = (int) round((copy[i][j].rgbtBlue + copy[i - 1][j].rgbtBlue + copy[i - 1][j + 1].rgbtBlue + copy[i][j + 1].rgbtBlue) / 4.0);
                    }

                    if (i == height - 1 && j == width - 1)
                    {
                        image[i][j].rgbtRed = (int) round((copy[i][j].rgbtRed + copy[i - 1][j].rgbtRed + copy[i - 1][j - 1].rgbtRed + copy[i][j - 1].rgbtRed) / 4.0);
                        image[i][j].rgbtGreen = (int) round((copy[i][j].rgbtGreen + copy[i - 1][j].rgbtGreen + copy[i - 1][j - 1].rgbtGreen + copy[i][j - 1].rgbtGreen) / 4.0);
                        image[i][j].rgbtBlue = (int) round((copy[i][j].rgbtBlue + copy[i - 1][j].rgbtBlue + copy[i - 1][j - 1].rgbtBlue + copy[i][j - 1].rgbtBlue) / 4.0);
                    }
                }
                // if not a corner index
                else
                {
                    if (i == 0 && (j >= 1 && j <= width - 2))
                    {
                        image[i][j].rgbtRed = (int) round((copy[i][j].rgbtRed + copy[i][j - 1].rgbtRed + copy[i][j + 1].rgbtRed + copy[i + 1][j].rgbtRed + copy[i + 1][j - 1].rgbtRed + copy[i + 1][j + 1].rgbtRed) / 6.0);
                        image[i][j].rgbtGreen = (int) round((copy[i][j].rgbtGreen + copy[i][j - 1].rgbtGreen + copy[i][j + 1].rgbtGreen + copy[i + 1][j].rgbtGreen + copy[i + 1][j - 1].rgbtGreen + copy[i + 1][j + 1].rgbtGreen) / 6.0);
                        image[i][j].rgbtBlue = (int) round((copy[i][j].rgbtBlue + copy[i][j - 1].rgbtBlue + copy[i][j + 1].rgbtBlue + copy[i + 1][j].rgbtBlue + copy[i + 1][j - 1].rgbtBlue + copy[i + 1][j + 1].rgbtBlue) / 6.0);
                    }

                    if ((i >= 1 && i <= height - 2) && j == 0)
                    {
                        image[i][j].rgbtRed = (int) round((copy[i][j].rgbtRed + copy[i - 1][j].rgbtRed + copy[i + 1][j].rgbtRed + copy[i][j + 1].rgbtRed + copy[i - 1][j + 1].rgbtRed + copy[i + 1][j + 1].rgbtRed) / 6.0);
                        image[i][j].rgbtGreen = (int) round((copy[i][j].rgbtGreen + copy[i - 1][j].rgbtGreen + copy[i + 1][j].rgbtGreen + copy[i][j + 1].rgbtGreen + copy[i - 1][j + 1].rgbtGreen + copy[i + 1][j + 1].rgbtGreen) / 6.0);
                        image[i][j].rgbtBlue = (int) round((copy[i][j].rgbtBlue + copy[i - 1][j].rgbtBlue + copy[i + 1][j].rgbtBlue + copy[i][j + 1].rgbtBlue + copy[i - 1][j + 1].rgbtBlue + copy[i + 1][j + 1].rgbtBlue) / 6.0);
                    }

                    if (i == height - 1 && (j >= 1 && j <= width - 2))
                    {
                        image[i][j].rgbtRed = (int) round((copy[i][j].rgbtRed + copy[i - 1][j].rgbtRed + copy[i][j - 1].rgbtRed + copy[i][j + 1].rgbtRed + copy[i - 1][j + 1].rgbtRed + copy[i - 1][j - 1].rgbtRed) / 6.0);
                        image[i][j].rgbtGreen = (int) round((copy[i][j].rgbtGreen + copy[i - 1][j].rgbtGreen + copy[i][j - 1].rgbtGreen + copy[i][j + 1].rgbtGreen + copy[i - 1][j + 1].rgbtGreen + copy[i - 1][j - 1].rgbtGreen) / 6.0);
                        image[i][j].rgbtBlue = (int) round((copy[i][j].rgbtBlue + copy[i - 1][j].rgbtBlue + copy[i][j - 1].rgbtBlue + copy[i][j + 1].rgbtBlue + copy[i - 1][j + 1].rgbtBlue + copy[i - 1][j - 1].rgbtBlue) / 6.0);
                    }

                    if ((i >= 1 && i <= height -2) && j == width - 1)
                    {
                        image[i][j].rgbtRed = (int) round((copy[i][j].rgbtRed + copy[i - 1][j].rgbtRed + copy[i + 1][j].rgbtRed + copy[i][j - 1].rgbtRed + copy[i - 1][j - 1].rgbtRed + copy[i + 1][j - 1].rgbtRed) / 6.0);
                        image[i][j].rgbtGreen = (int) round((copy[i][j].rgbtGreen + copy[i - 1][j].rgbtGreen + copy[i + 1][j].rgbtGreen + copy[i][j - 1].rgbtGreen + copy[i - 1][j - 1].rgbtGreen + copy[i + 1][j - 1].rgbtGreen) / 6.0);
                        image[i][j].rgbtBlue = (int) round((copy[i][j].rgbtBlue + copy[i - 1][j].rgbtBlue + copy[i + 1][j].rgbtBlue + copy[i][j - 1].rgbtBlue + copy[i - 1][j - 1].rgbtBlue + copy[i + 1][j - 1].rgbtBlue) / 6.0);
                    }
                }
            }
            // for normal pixel no edge at all
            else
            {
                image[i][j].rgbtRed = (int) round(((copy[i - 1][j - 1].rgbtRed) + (copy[i - 1][j].rgbtRed) + (copy[i - 1][j + 1].rgbtRed) + (copy[i][j - 1].rgbtRed) + (copy[i][j].rgbtRed) + (copy[i][j + 1].rgbtRed) + (copy[i + 1][j - 1].rgbtRed) + (copy[i + 1][j].rgbtRed) + (copy[i + 1][j + 1].rgbtRed)) / 9.0);
                image[i][j].rgbtGreen = (int) round(((copy[i - 1][j - 1].rgbtGreen) + (copy[i - 1][j].rgbtGreen) + (copy[i - 1][j + 1].rgbtGreen) + (copy[i][j - 1].rgbtGreen) + (copy[i][j].rgbtGreen) + (copy[i][j + 1].rgbtGreen) + (copy[i + 1][j - 1].rgbtGreen) + (copy[i + 1][j].rgbtGreen) + (copy[i + 1][j + 1].rgbtGreen)) / 9.0);
                image[i][j].rgbtBlue = (int) round(((copy[i - 1][j - 1].rgbtBlue) + (copy[i - 1][j].rgbtBlue) + (copy[i - 1][j + 1].rgbtBlue) + (copy[i][j - 1].rgbtBlue) + (copy[i][j].rgbtBlue) + (copy[i][j + 1].rgbtBlue) + (copy[i + 1][j - 1].rgbtBlue) + (copy[i + 1][j].rgbtBlue) + (copy[i + 1][j + 1].rgbtBlue)) / 9.0);
            }

        }
    }

    return;
}

【讨论】:

    猜你喜欢
    • 2013-03-02
    • 1970-01-01
    • 2019-08-24
    • 1970-01-01
    • 2014-06-22
    • 2015-08-29
    • 2018-05-25
    • 2017-09-05
    • 1970-01-01
    相关资源
    最近更新 更多