CS50 PSET4的模糊功能,错误在哪里?

时间:2020-07-14 15:38:59

标签: c filter blur cs50

我已经被这个功能困扰了好几天了。我看了别人的问题,看了YouTube教程视频,但听不清。 该任务是哈佛大学CS50课程(https://cs50.harvard.edu/x/2020/psets/4/filter/less/)的一部分。 任何帮助将不胜感激!我真的不想在不理解问题所在的情况下继续学习该课程。

//check if pixels are valid
bool valid_pixel(int r, int c, int height, int width)
{
    return r >= 0 && c >= 0 && r < height && c < width;
}

// Blur image
void blur(int height, int width, RGBTRIPLE image[height][width])
{
    //create a copy of the original image
    RGBTRIPLE temp[height][width];
    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            temp[i][j] = image[i][j];
        }
    }

    int red, green, blue, count;
    red = green = blue = count = 0;
    //iterate through rows
    for (int i = 0; i < height; i++)
    {
        //iterate through columns
        for (int j = 0; j < width; j++)
        {
            //move one pixel up to one pixel down in the rows
            for (int r = i - 1; r <= i + 1; r++)
            {
                //move one pixel left to one pixel right in the columns
                for (int c = j - 1; c <= j + 1; c++)
                {
                    //check if they are unvalid pixels
                    if (valid_pixel(r, c, height, width))
                    {
                        //count every valid pixel
                        count ++;
                        //"store" every pixel color
                        red += image[r][c].rgbtRed;
                        green += image[r][c].rgbtGreen;
                        blue += image[r][c].rgbtBlue;
                    }
                }
            }
            //calculate average values
            temp[i][j].rgbtRed = round((float)red / count);
            temp[i][j].rgbtGreen = round((float)green / count);
            temp[i][j].rgbtBlue = round((float)blue / count);
        }
    }

    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            image[i][j] = temp[i][j];
        }
    }
    return;

1 个答案:

答案 0 :(得分:0)

主要问题是,每次外部循环迭代后,您忘记重置redbluegreen变量(您总结)。您应该将此行放入主循环内-

red = green = blue = count = 0;

此外,您还将图像复制到另一个临时图像中,最后再次将该临时图像复制到原始图像中。这是非常低效的。首先,您不应该将像素从原始图像复制到模糊图像。您可以将修改后的值直接放入此临时映像中。最后,使用memmove一次将整个行有效地移动到原始图像。 (请记住#include <string.h>

void blur(int height, int width, RGBTRIPLE image[height][width])
{
    
    RGBTRIPLE blurred_img[height][width];
    //iterate through rows
    for (int i = 0; i < height; i++)
    {
        //iterate through columns
        for (int j = 0, red, green, blue, count; j < width; j++)
        {
            // Reset the variables
            red = blue = green = count = 0;
            //move one pixel up to one pixel down in the rows
            for (int r = i - 1; r <= i + 1; r++)
            {
                //move one pixel left to one pixel right in the columns
                for (int c = j - 1; c <= j + 1; c++)
                {
                    //check if they are unvalid pixels
                    if (valid_pixel(r, c, height, width))
                    {
                        //count every valid pixel
                        count++;
                        //"store" every pixel color
                        red += image[r][c].rgbtRed;
                        green += image[r][c].rgbtGreen;
                        blue += image[r][c].rgbtBlue;
                    }
                }
            }
            //calculate average values
            blurred_img[i][j].rgbtRed = round((float)red / count);
            blurred_img[i][j].rgbtGreen = round((float)green / count);
            blurred_img[i][j].rgbtBlue = round((float)blue / count);
        }
    }
    for (int i = 0; i < height; i++)
    {
        // Copy the new image over to the original, row by row
        memmove(image[i], blurred_img[i], sizeof(RGBTRIPLE) * width);
    }
    return;
}

这是假设valid_pixel是正确的。要确定像素位置是否有效,您可以执行以下操作-

if (k > 0 && k < height && l > -1 && l < width))

但是请注意,当r(行)无效时,最里面的循环(列循环)仍会迭代直到c == width,即使该循环的整个过程都是无用的,因为{{1} }是无效的,它将一直保持这种状态,直到最内层的循环完成并且r递增为止。

为了提高效率,只要r无效,就应该break-

r