CS50 无滤镜(模糊)代码在图像上工作但仅通过 1/5 检查时出现问题

问题描述 投票:0回答:1

我对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..."
c cs50
1个回答
0
投票

作业包含以下提示:

在实现

blur
函数时,您可能会发现模糊一个像素最终会影响另一个像素的模糊。最好通过使用类似
image
的代码声明一个新的二维数组来创建
RGBTRIPLE copy[height][width];
的副本。然后将
image
复制到
copy
中,逐个像素,使用嵌套 for 循环,如下所示:

[代码省略]

如果您遵循此提示,则应在处理任何像素之前完成此复制操作。

或者,您可以将结果写入单独的数组,而不是遵循此提示,当您完成所有像素后,您可以将这些结果复制回

image

但是,您似乎没有做上述任何事情。相反,您可以执行以下操作:

  • 您无需在处理任何像素之前复制整个图像,而是在处理该像素之前仅复制单个像素。但是,此副本没有任何效果,因为您立即用其他内容覆盖了该副本。
  • 将模糊像素值结果写入
    copy
    ,然后将该值写回
    image
    。如上所述,如果您首先将所有结果写入
    copy
    ,然后将这些结果复制到
    image
    ,这将是一个可行的解决方案(尽管在这种情况下,您可能应该将数组从
    copy
    重命名为
    results
    ) ,因为
    copy
    是一个误导性的名称)。然而,这不是你正在做的事情。相反,您会立即将结果写入
    image
    ,这将影响其他像素的模糊计算。这是错误的,因为您必须使用原始像素数据来计算所有像素的模糊。

另一个问题是,对整数调用

round
没有意义。在将结果转换为整数之前,您应该调用
round

© www.soinside.com 2019 - 2024. All rights reserved.