Suhana66
Suhana66

Reputation: 25

Why does the filter work for pixels in a corner but doesn't work for anything else?

This is my failed solution to Problem Set 4 of CS50 2020 "Introduction to Computer Science" by Harvard University. Problem Set 4 Filter(less)- https://cs50.harvard.edu/x/2020/psets/4/filter/less/

I have been struggling to find the bug in this code for the past day. Having read through the code multiple times, it seems logically correct. The output file seems blurred but the code fails the check50 text.

// Blur image
void blur(int height, int width, RGBTRIPLE image[height][width])
{
    // Iterating through each row
    for (int i = 0; i < height; i++)
    {
        // Iterating through each pixel in a row
        for (int j = 0; j < width; j++)
        {
            // Declaring variables required to calculate average
            float total_b = 0;
            float total_g = 0;
            float total_r = 0;
            int counter = 0;
    
            // Creating a copy of the image
            RGBTRIPLE tmp[height][width];
            tmp[i][j] = image[i][j];
    
            // Checking if top-right neighbouring pixel is out of bounds
            if ( i - 1 >= 0 && j + 1 < width)
            {
                total_b += image[i - 1][j + 1].rgbtBlue;
                total_g += image[i - 1][j + 1].rgbtGreen;
                total_r += image[i - 1][j + 1].rgbtRed;
                counter++;
            }
    
            // Checking if top neighbouring pixel is out of bounds
            if (i - 1 >= 0)
            {
                total_b += image[i - 1][j].rgbtBlue;
                total_g += image[i - 1][j].rgbtGreen;
                total_r += image[i - 1][j].rgbtRed;
                counter++;
            }
    
            // Checking if top-left neighbouring pixel is out of bounds
            if (i - 1 >= 0 && j - 1 >= 0)
            {
                total_b += image[i - 1][j - 1].rgbtBlue;
                total_g += image[i - 1][j - 1].rgbtGreen;
                total_r += image[i - 1][j - 1].rgbtRed;
                counter++;
            }
    
            // Checking if left neighbouring pixel is out of bounds
            if (j - 1 >= 0)
            {
                total_b += image[i][j - 1].rgbtBlue;
                total_g += image[i][j - 1].rgbtGreen;
                total_r += image[i][j - 1].rgbtRed;
                counter++;
            }
    
            // Checking if bottom-left neighbouring pixel is out of bounds
            if (i + 1 < height && j - 1 >= 0)
            {
                total_b += image[i + 1][j - 1].rgbtBlue;
                total_g += image[i + 1][j - 1].rgbtGreen;
                total_r += image[i + 1][j - 1].rgbtRed;
                counter++;
            }
    
            // Checking if bottom neighbouring pixel is out of bounds
            if (i + 1 < height)
            {
                total_b += image[i + 1][j].rgbtBlue;
                total_g += image[i + 1][j].rgbtGreen;
                total_r += image[i + 1][j].rgbtRed;
                counter++;
            }
    
            // Checking if bottom-right neighbouring pixel is out of bounds
            if (i + 1 < height && j + 1 < width)
            {
                total_b += image[i + 1][j + 1].rgbtBlue;
                total_g += image[i + 1][j + 1].rgbtGreen;
                total_r += image[i + 1][j + 1].rgbtRed;
                counter++;
            }
    
            // Checking if right neighbouring pixel is out of bounds
            if (j + 1 < width)
            {
                total_b += image[i][j + 1].rgbtBlue;
                total_g += image[i][j + 1].rgbtGreen;
                total_r += image[i][j + 1].rgbtRed;
                counter++;
            }
    
            // Adding the values of the middle pixel to the total
            total_b += image[i][j].rgbtBlue;
            total_g += image[i][j].rgbtGreen;
            total_r += image[i][j].rgbtRed;
            counter++;
    
            // Calculating the new values of rgb required
            tmp[i][j].rgbtBlue = round(total_b / counter);
            tmp[i][j].rgbtGreen = round(total_g / counter);
            tmp[i][j].rgbtRed = round(total_r / counter);
    
            // Changing the values of the original image
            image[i][j].rgbtBlue = tmp[i][j].rgbtBlue;
            image[i][j].rgbtGreen = tmp[i][j].rgbtGreen;
            image[i][j].rgbtRed = tmp[i][j].rgbtRed;
        }
    }

    return;
}

Check50 gives the following result-

:( 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..."

Upvotes: 1

Views: 170

Answers (1)

John Kugelman
John Kugelman

Reputation: 362037

You're modifying the image as you go, overwriting the pixels in image each iteration. When you're blurring a pixel the ones to the top and left will have already been blurred, which causes the values to come out wrong.

You'll want to modify the code to preserve the original pixels longer and not overwrite them as you go. The simplest way is to simply create a blurred copy of the source image and only overwrite image after the loops are finished.

Upvotes: 1

Related Questions