1

I'm having an issue with the blur filter; when working with Duck to understand how to structure my code, I was able to come up with a solution, but the output image was darkened and blurred up until the last row or two. Here's the original: Harvard courtyard picture

And here's the blurred:

darker, blurred Harvard courtyard picture

I tried using the 3x3 image for debugging too but I'm not sure how to understand what's happening:

check50 automated test results for 3x3 image

I'll share my code here too, but if it's inappropriate for me to do so, I'll adjust my question accordingly, so as to observe academic honesty. Do you have any suggestions as to what I should try and change/look at more closely?

void blur(int height, int width, RGBTRIPLE image[height][width])
{
    // Create a copy of image
    RGBTRIPLE copy[height][width];

    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            copy[i][j] = image[i][j];
            float pixel_count = 0.0;
            int blue_sum = 0;
            int green_sum = 0;
            int red_sum = 0;

            for(int k = i-1; k < height && k <= i + 1; k++)
            {
                for(int l = j-1; l < width && l <= j + 1 ; l++)
                {
                        if (k >= 0 && l >= 0)
                        {
                            blue_sum += copy[k][l].rgbtBlue;
                            green_sum += copy[k][l].rgbtGreen;
                            red_sum += copy[k][l].rgbtRed;
                            pixel_count += 1;
                        }

                }
            }

            float blue_avg = (blue_sum / pixel_count);
            float green_avg = (green_sum / pixel_count);
            float red_avg = (red_sum / pixel_count);

            int average_blue = round(blue_avg);
            int average_green = round(green_avg);
            int average_red = round(red_avg);

            image[i][j].rgbtBlue = average_blue;
            image[i][j].rgbtGreen = average_green;
            image[i][j].rgbtRed = average_red;

            // For debugging to compare to expected output
            printf("%i %i %i\n", image[i][j].rgbtRed,
            image[i][j].rgbtGreen, image[i][j].rgbtBlue);



        }
    }

    return;
}
1
  • kudo's and upvote for actually attempting debugging of your own through printing and posting some of the value differences, for posting the code as code and the relevant images. Very well stated and well defined question. the answer is fairly trivial but you asked the question better than a LOT of folks here tend to and I think that will serve you very well! You did this so well I would strongly encourage you to look at filter-more! I think you'll be able to handle it and I'm happy to help you along the way
    – UpAndAdam
    Commented May 16 at 18:33

1 Answer 1

1

You need to do a full copy of the initial image into copy before you do anything else at all.

You are currently encountering consistent and explainable but undefined behavior as you are reading data from copy in areas you have yet to initialize with a value during your blurring algo. The observed result is they appear to have been defaulted to 0,0,0 and the result is you are darkening things and not properly blurring.

i.e.

void blur(int height, int width, RGBTRIPLE image[height][width])
{
    // Create a copy of image
    RGBTRIPLE copy[height][width];

    // perform the whole copy routine first
    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            copy[i][j] = image[i][j];
        }
    }

    for ( int i = 0; i < height; i++ )
    {
        for (int j = 0; j < width; j++ )
        {
            float pixel_count = 0.0;
            int blue_sum = 0;
            int green_sum = 0;
            int red_sum = 0;

            for(int k = i-1; k < height && k <= i + 1; k++)
            {
                for(int l = j-1; l < width && l <= j + 1 ; l++)
                {
                    if (k >= 0 && l >= 0)
                    {
                        // NOTE******** 
                        // Do you see how HERE k and l would refer to locations in copy that you wouldn't have yet written to in your old code here??
                        blue_sum += copy[k][l].rgbtBlue;
                        green_sum += copy[k][l].rgbtGreen;
                        red_sum += copy[k][l].rgbtRed;
                        pixel_count += 1;
                    }
                }
            }

            //...
        }
    }
}

3
  • Thanks for the pointer -- could you clarify what you mean by doing the full copy?
    – Manny
    Commented May 16 at 17:39
  • Ah --I see. When I had it inside the loop before, it kept on reinitializing the copy; if I allow it to complete first, there ideally shouldn't be any issue in accessing the values of the copy as they would already be there. Am I understanding you correctly?
    – Manny
    Commented May 16 at 17:50
  • it didnt reinitialize the copy, that was the copy operation. the problem is that you are referencing 'data' in the copy that you havent copied yet so those act as black cells. consider the first cells evaluation you copy image[0][0] to copy[0][0] then you loop through values of copy for [-1:1][-1:1] with limits such that -1 isn't accessed but 0,1 and 1,0 and 1,1 are but you haven't copied image[r][c] into that copy[r][c] yet. thats the problem . if this answers your questions please mark answer as accepted, i do appreciate the upvote as well :-) glad i was helpful
    – UpAndAdam
    Commented May 16 at 18:28

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .