0

I'm working on a solution to Pset4 blur and have hit a roadblock. My aim is to create average RGB values from a 3x3 grid surrounding and including current pixel and change pixel in original image to the new average value (taking into account corners and borders). I'm doing this by creating a copy of the original image, calculating my averages off of that, and then writing the values to the original image.

Anyway my program hasn't reached the stage of creating a new image, unfortunately I'm seeing a 'runtime error'. I've figured some the values I'm calculating for average RGB exceed the max 255 that can be stored in the BYTE variable for RGB. I confirmed this by printf-ing any values that were higher than 255, as suspected there were a bunch of them. However I've double checked my maths and can't seem to locate where I'm going wrong, as far as I can see I'm adding a max of 9 values, then dividing by 9 (or lower if less values were used). Any help much appreciated.

// Blur image
void blur(int height, int width, RGBTRIPLE image[height][width])
{
// create copy of image to work from
    RGBTRIPLE og_image[height][width];
    for (int h = 0; h < height - 1; h++)
    {
        for (int w = 0; w < width - 1; w++)
        {
            og_image[h][w].rgbtBlue = image[h][w].rgbtBlue;
            og_image[h][w].rgbtGreen = image[h][w].rgbtGreen;
            og_image[h][w].rgbtRed = image[h][w].rgbtRed;
        }
    }

// create floats to track rgb totals and int to count how many pixel used in 3x3 grid
    float *blur_countb = malloc(sizeof (float));
    float *blur_countg = malloc(sizeof (float));
    float *blur_countr = malloc(sizeof (float));
    int int_grid_count = 0;
    int *grid_count = &int_grid_count;

    for (int h = 0; h < height - 1; h++)
    {
        for (int w = 0; w < width - 1; w++)
        {
            if ((h > 0) && (h < height - 1) && (w > 0) && (w < width - 1)) // for pixels in the MIDDLE SECTION

            {
                for (int i = -1; i < 2; i++) // 3x3 grid around and including current pixel
                {
                    *blur_countb += (og_image[h - 1][w + i].rgbtBlue + og_image[h][w + i].rgbtBlue + og_image[h + 1][w + i].rgbtBlue);
                    *blur_countg += (og_image[h - 1][w + i].rgbtGreen + og_image[h][w + i].rgbtGreen + og_image[h + 1][w + i].rgbtGreen);
                    *blur_countr += (og_image[h - 1][w + i].rgbtRed + og_image[h][w + i].rgbtRed + og_image[h + 1][w + i].rgbtRed);
                }
                *grid_count += 9;
            }
            

            else if ((h == 0) && (w > 0) && (w < width -1)) // pixels in the TOP ROW (not corners)
            {
                for (int i = -1; i < 2; i++) // 2x3 grid 
                {
                    *blur_countb += (og_image[h][w + i].rgbtBlue + og_image[h + 1][w + i].rgbtBlue);
                    *blur_countg += (og_image[h][w + i].rgbtGreen + og_image[h + 1][w + i].rgbtGreen);
                    *blur_countr += (og_image[h][w + i].rgbtRed + og_image[h + 1][w + i].rgbtRed);
                }
                *grid_count += 6;
            }

            else if ((h == height - 1) && (w > 0) && (w < width -1)) // pixels in the BOTTOM ROW (not corners)
            {
                for (int i = -1; i < 2; i++) // 2x3 grid
                {
                    *blur_countb += (og_image[h][w + i].rgbtBlue + og_image[h - 1][w + i].rgbtBlue);
                    *blur_countg += (og_image[h][w + i].rgbtGreen + og_image[h - 1][w + i].rgbtGreen);
                    *blur_countr += (og_image[h][w + i].rgbtRed + og_image[h - 1][w + i].rgbtRed);
                }
                *grid_count += 6;
            }

            else if ((w == 0) && (h > 0) && (h < height - 1)) // pixels in the FIRST COLUMN (not corners)
            {
                for (int i = -1; i < 2; i++) // 2x3 grid
                {
                    *blur_countb += (og_image[h + i][w].rgbtBlue + og_image[h + i][w + 1].rgbtBlue);
                    *blur_countg += (og_image[h + i][w].rgbtGreen + og_image[h + i][w + 1].rgbtGreen);
                    *blur_countr += (og_image[h + i][w].rgbtRed + og_image[h + i][w + 1].rgbtRed);
                }
                *grid_count += 6;
            }

            else if ((w == width - 1) && (h > 0) && (h < height - 1)) // pixels in the LAST COLUMN (not corners)
            {
                for (int i = -1; i < 2; i++) // 3x2 grid
                {
                    *blur_countb += (og_image[h + i][w].rgbtBlue + og_image[h + i][w - 1].rgbtBlue);
                    *blur_countg += (og_image[h + i][w].rgbtGreen + og_image[h + i][w - 1].rgbtGreen);
                    *blur_countr += (og_image[h + i][w].rgbtRed + og_image[h + i][w - 1].rgbtRed);
                }
                *grid_count += 6;
            }

            // TOP LEFT CORNER
            else if ((h == 0) && (w == 0))
            {
                for (int i = 0; i < 2; i++) // 2x2 grid
                {
                    *blur_countb += (og_image[h + i][w].rgbtBlue + og_image[h][w + i].rgbtBlue);
                    *blur_countg += (og_image[h + i][w].rgbtGreen + og_image[h][w + i].rgbtGreen);
                    *blur_countr += (og_image[h + i][w].rgbtRed + og_image[h][w + i].rgbtRed);
                }
                *grid_count += 4;
            }

            // TOP RIGHT CORNER
            else if ((h == 0) && (w == width - 1))
            {
                for (int i = 0; i < 2; i++) // 2x2 grid
                {
                    *blur_countb += (og_image[h + i][w].rgbtBlue + og_image[h][w - i].rgbtBlue);
                    *blur_countg += (og_image[h + i][w].rgbtGreen + og_image[h][w - i].rgbtGreen);
                    *blur_countr += (og_image[h + i][w].rgbtRed + og_image[h][w - i].rgbtRed);
                }
                *grid_count += 4;
            }

            // BOTTOM LEFT CORNER
            else if ((h == height - 1) && (w == 0))
            {
                for (int i = 0; i < 2; i++) 2x2 grid
                {
                    *blur_countb += (og_image[h - i][w].rgbtBlue + og_image[h][w + i].rgbtBlue);
                    *blur_countg += (og_image[h - i][w].rgbtGreen + og_image[h][w + i].rgbtGreen);
                    *blur_countr += (og_image[h - i][w].rgbtRed + og_image[h][w + i].rgbtRed);
                }
                *grid_count += 4;
            }

            // BOTTOM RIGHT CORNER
           else if ((h == height - 1) && (w == width - 1))
            {
                for (int i = 0; i < 2; i++) // 2x2 grid
                {
                    *blur_countb += (og_image[h - i][w].rgbtBlue + og_image[h][w - i].rgbtBlue);
                    *blur_countg += (og_image[h - i][w].rgbtGreen + og_image[h][w - i].rgbtGreen);
                    *blur_countr += (og_image[h - i][w].rgbtRed + og_image[h][w - i].rgbtRed);
                }
                *grid_count += 4;
            }
            
            // calculate average RGB blur values
            *blur_countb = round (*blur_countb / *grid_count);
            *blur_countg = round (*blur_countg / *grid_count);
            *blur_countr = round (*blur_countr / *grid_count);
            
            // change original image current pixel to blurred pixel
            image[h][w].rgbtBlue = (BYTE) *blur_countb;
            image[h][w].rgbtGreen = (BYTE) *blur_countg;
            image[h][w].rgbtRed = (BYTE) *blur_countr;

            // reset grid_count counter
            *grid_count = 0;
        }
    }
    // End program
    return;
}

1 Answer 1

1

I recommend you use a for loop to check if there is not a pixel rounding the actual pixel. This should make mistakes disappear.

It should be really 2 for loops, 1 for width and 1 for height. "i" starting them at -1 (1 pixel before/above) and finalizing at "i < 2" (1 pixel after/bellow the main pixel). And with and "if" condition that checks if the pixel isn't valid. If is not valid just continue the loop. If is valid, add the pixel value to the total RGB values t and add 1 to the counter and when you finish the loop just divide the RGB total by the counter.

Something like this:

for (int w = -1; w < 2; w++)
        {
            for (int h = -1; h < 2; h++)
            {
                if (i + w < 0 || i + w > height - 1 || j + h < 0 || j + h > width - 1)
                {
                    continue;
                }

                sumRed += image[i + w][j + h].rgbtRed;
                sumGreen += image[i + w][j + h].rgbtGreen;
                sumBlue += image[i + w][j + h].rgbtBlue;

                counter++;
            }
1
  • Neat, thanks for the tips. Continue function was a mini revelation.
    – t-monny
    Commented Aug 25, 2020 at 10:56

You must log in to answer this question.

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