Bunnycorn
Bunnycorn

Reputation: 65

Blur function in CS50 pset4 not fully working

I've spent two days trying to correct my function for blurring a given image, but despite extensive proofreading it now only works correctly for corner cases. For the rest, it creates a discrepacy of 2-20+ in RGB values.

The task is part of Harvard's CS50 course (more info on pset4 https://cs50.harvard.edu/x/2020/psets/4/filter/less/).

I've read everything I could find online and tried using those hacks like dividing new RGB values with a float, copying results directly back into the original image, tweaking the if condition, but that didn't help and I still have no idea what's wrong. Would greatly appreciate help, thank you!

 // Blur image
 void blur(int height, int width, RGBTRIPLE image[height][width])
 {
    float new_red, new_blue, new_green;
    new_red = new_blue = new_green = 0;

    int count = 0;

    // Copy the 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];
        }
    }

    // Loop through height
    for (int i = 0; i < height; i++)
    {
        // Loop through width
        for (int j = 0; j < width; j++)
        {
            // Loop through rows around a pixel
            for (int k = -1; k <= 1; k++)
            {
                // Loop through columns around a pixel
                for (int m = -1; m <= 1; m++)
                {
                    if (i + k >= 0 && i + k < height && j + m >= 0 && j + m < width)
                    {
                        count++;
                        new_red += temp[i + k][j + m].rgbtRed;
                        new_blue += temp[i + k][j + m].rgbtBlue;
                        new_green += temp[i + k][j + m].rgbtGreen;
                    }
                }
            }

            temp[i][j].rgbtBlue = round(new_blue / count);
            temp[i][j].rgbtRed = round(new_red / count);
            temp[i][j].rgbtGreen = round(new_green / count);
        }

    }

    // Copy the blurred image to original file
    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            image[i][j] = temp[i][j];
        }
    }

    return;
}

Upvotes: 1

Views: 342

Answers (1)

Jeff
Jeff

Reputation: 1264

I assume you'll want to reset count, new_blue, new_red, and new_green for each pixel. In your code these values continue to grow as you process the the image.

// Loop through height
for (int i = 0; i < height; i++)
{
    // Loop through width
    for (int j = 0; j < width; j++)
    {
        count = new_blue = new_red = new_green = 0;

One way you could have caught this while debugging is by printing out the values of these variables for each pixel before doing the division and assignment. You might have noticed that the count value was too high.

I believe another issue is that you are blurring pixels in place in your temporary image. When you blur a pixel you'll be using the already-blurred values of the pixels above it. Instead you probably want to use the original image in your inner-most loop:

                    new_red += image[i + k][j + m].rgbtRed;
                    new_blue += image[i + k][j + m].rgbtBlue;
                    new_green += image[i + k][j + m].rgbtGreen

Upvotes: 2

Related Questions