首页 > 解决方案 > CS50 模糊功能未通过 check50,即使图像正在模糊

问题描述

我正在研究一个 CS50 问题集,其中我需要为图像的每个像素做一个框模糊。虽然我的代码有点多余,因为我为像素的特殊情况(如边缘和角落)创建了 8 个 if 语句,但它会按预期模糊图像,所以我不确定如何解决这个问题。这是错误代码:

:( 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
void blur(int height, int width, RGBTRIPLE image[height][width])
{
    int blue;
    int green;
    int red;
    int counter = 0;

    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            if (i == 0 && j == 0)
            {
                // top left corner
                blue  = (image[i][j].rgbtBlue  + image[i + 1][j].rgbtBlue  + image[i][j+1].rgbtBlue  + image[i + 1][j+1].rgbtBlue);
                green = (image[i][j].rgbtGreen + image[i + 1][j].rgbtGreen + image[i][j+1].rgbtGreen + image[i + 1][j+1].rgbtGreen);
                red   = (image[i][j].rgbtRed   + image[i + 1][j].rgbtRed   + image[i][j+1].rgbtRed   + image[i + 1][j+1].rgbtRed);
                counter = 4;
            }

            else if (i == 0 && j == (width - 1))
            {
                // top right corner
                blue  = (image[i][j].rgbtBlue  + image[i + 1][j].rgbtBlue  + image[i][j-1].rgbtBlue  + image[i + 1][j-1].rgbtBlue);
                green = (image[i][j].rgbtGreen + image[i + 1][j].rgbtGreen + image[i][j-1].rgbtGreen + image[i + 1][j-1].rgbtGreen);
                red   = (image[i][j].rgbtRed   + image[i + 1][j].rgbtRed   + image[i][j-1].rgbtRed   + image[i + 1][j-1].rgbtRed);
                counter = 4;
            }

            else if (i == 0 && (j != 0 || j != (width - 1)))
            {
                // top edge
                blue  = (image[i][j - 1].rgbtBlue  + image[i][j].rgbtBlue  + image[i][j + 1].rgbtBlue  + image[i + 1][j].rgbtBlue  + image[i+1][j - 1].rgbtBlue  + image[i + 1][j + 1].rgbtBlue);
                green = (image[i][j - 1].rgbtGreen + image[i][j].rgbtGreen + image[i][j + 1].rgbtGreen + image[i + 1][j].rgbtGreen + image[i+1][j - 1].rgbtGreen + image[i + 1][j + 1].rgbtGreen);
                red   = (image[i][j - 1].rgbtRed   + image[i][j].rgbtRed   + image[i][j + 1].rgbtRed   + image[i + 1][j].rgbtRed   + image[i+1][j - 1].rgbtRed   + image[i + 1][j + 1].rgbtRed);
                counter = 6;
            }

            else if (i == (height - 1) && j == 0)
            {
                // bottom left corner
                blue  = (image[i-1][j + 1].rgbtBlue  + image[i][j + 1].rgbtBlue  + image[i - 1][j].rgbtBlue  + image[i][j].rgbtBlue);
                green = (image[i-1][j + 1].rgbtGreen + image[i][j + 1].rgbtGreen + image[i - 1][j].rgbtGreen + image[i][j].rgbtGreen);
                red   = (image[i-1][j + 1].rgbtRed   + image[i][j + 1].rgbtRed   + image[i - 1][j].rgbtRed   + image[i][j].rgbtRed);
                counter = 4;
            }

            else if (i == (height - 1) && j == (width - 1))
            {
                // bottom right corner
                blue  = (image[i][j].rgbtBlue  + image[i - 1][j].rgbtBlue  + image[i][j-1].rgbtBlue  + image[i - 1][j-1].rgbtBlue);
                green = (image[i][j].rgbtGreen + image[i - 1][j].rgbtGreen + image[i][j-1].rgbtGreen + image[i - 1][j-1].rgbtGreen);
                red   = (image[i][j].rgbtRed   + image[i - 1][j].rgbtRed   + image[i][j-1].rgbtRed   + image[i - 1][j-1].rgbtRed);
                counter = 4;
            }

            else if (i == (height - 1) && (j != 0 || j != (width - 1)))
            {
                // bottom edge
                blue  = (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);
                green = (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);
                red   = (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);
                counter = 6;
            }

            else if (j == 0 && (i != 0 || i != (height - 1)))
            {
                // left edge
                blue  = (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);
                green = (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);
                red   = (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);
                counter = 6;
            }

            else if (j == (width - 1) && (i != 0 || i != (height - 1)))
            {
                // right edge
                blue  = (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);
                green = (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);
                red   = (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);
                counter = 6;
            }

            else
            {
                blue  = (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);
                green = (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);
                red   = (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);
                counter = 9;
            }

            image[i][j].rgbtBlue  = round((float) blue / counter);
            image[i][j].rgbtGreen = round((float) green / counter);
            image[i][j].rgbtRed   = round((float) red / counter);
        }
    }
    return;
}

查看其他人对同一问题的答案,我看到有些人制作了第二个嵌套for循环来存储像素的原始值。我最初试图实现这一点,但它最终导致了问题,所以我认为没有必要。这是我的代码的问题吗?如果是这样,我将如何在我的代码中正确实现“原始值”像素?如果没有,有人知道问题所在吗?提前致谢。

标签: cpixelblurcs50

解决方案


image当您将模糊功能应用于像素时,您正在修改您的。这意味着当您修改几个像素时,相邻像素的模糊值是使用“模糊像素值”计算的。这是错误的。所有计算都必须在原始图像像素值内完成。为此,您应该image在开头创建一个副本(例如temp)并在该图像中进行所有这些计算,该temp图像具有未修改的像素值。

将此添加到代码的开头;

RGBTRIPLE temp[height][width]; // create a temporary array to store a duplicate of image.

// save a new copy of image as temp per color.
for (int i = 0; i < height; i++) //Loop for height of image.
{
    for (int j = 0; j < width; j++) //Loop for width of image and save color values in temp.
    {
        temp[i][j] = image[i][j];
    }
}

并在您的计算中替换imagetemp(最后的作业除外)。


推荐阅读