I am trying to blur an image based on the tutorial I am following. Here's the instruction.
Blur There are a number of ways to create the effect of blurring or softening an image. For this problem, we’ll use the “box blur,” which works by taking each pixel and, for each color value, giving it a new value by averaging the color values of neighboring pixels.
Consider the following grid of pixels, where we’ve numbered each pixel.
a grid of pixels
The new value of each pixel would be the average of the values of all of the pixels that are within 1 row and column of the original pixel (forming a 3x3 box). For example, each of the color values for pixel 6 would be obtained by averaging the original color values of pixels 1, 2, 3, 5, 6, 7, 9, 10, and 11 (note that pixel 6 itself is included in the average). Likewise, the color values for pixel 11 would be be obtained by averaging the color values of pixels 6, 7, 8, 10, 11, 12, 14, 15 and 16.
For a pixel along the edge or corner, like pixel 15, we would still look for all pixels within 1 row and column: in this case, pixels 10, 11, 12, 14, 15, and 16.```
So to tackle this, I've come up with this solution.
for each row
for each column
add the pixel if upper left exists
add the pixel if directly above exists
add the pixel if upper right exists
add the pixel if right exists
add the pixel if directly below exists
add the pixel if left exists
divide by times added
and I have typed the code -
void blur(int height, int width, RGBTRIPLE image[height][width])
{
int red;
int green;
int blue;
int counter = 0;
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
if (i + 1 && j - 1)
{
red = image[i][j].rgbtRed + image[i + 1][j - 1].rgbtRed;
green = image[i][j].rgbtGreen + image[i + 1][j - 1].rgbtGreen;
blue = image[i][j].rgbtBlue + image[i + 1][j - 1].rgbtBlue;
counter++;
}
if (j + 1)
{
red = image[i][j].rgbtRed + image[i][j + 1].rgbtRed;
green = image[i][j].rgbtGreen + image[i][j + 1].rgbtGreen;
blue = image[i][j].rgbtBlue + image[i][j + 1].rgbtBlue;
counter++;
}
if (i + 1 && j + 1)
{
red = image[i][j].rgbtRed + image[i + 1][j + 1].rgbtRed;
green = image[i][j].rgbtGreen + image[i + 1][j + 1].rgbtGreen;
blue = image[i][j].rgbtBlue + image[i + 1][j + 1].rgbtBlue;
counter++;
}
if (i + 1)
{
red = image[i][j].rgbtRed + image[i + 1][j].rgbtRed;
green = image[i][j].rgbtGreen + image[i + 1][j].rgbtGreen;
blue = image[i][j].rgbtBlue + image[i + 1][j].rgbtBlue;
counter++;
}
if (j - 1)
{
red = image[i][j].rgbtRed + image[i][j - 1].rgbtRed;
green = image[i][j].rgbtGreen + image[i][j - 1].rgbtGreen;
blue = image[i][j].rgbtBlue + image[i][j - 1].rgbtBlue;
counter++;
}
if (i - 1)
{
red = image[i][j].rgbtRed + image[i - 1][j].rgbtRed;
green = image[i][j].rgbtGreen + image[i - 1][j].rgbtGreen;
blue = image[i][j].rgbtBlue + image[i - 1][j].rgbtBlue;
counter++;
}
image[i][j].rgbtRed = red/counter;
image[i][j].rgbtGreen = green/counter;
image[i][j].rgbtBlue = blue/counter;
}
}
return;
}
and it seems like I am getting errors saying
~/pset4/filter/ $ ./filter -b images/courtyard.bmp test.bmp
helpers.c:84:45: runtime error: index -1 out of bounds for type 'RGBTRIPLE [width]'
helpers.c:85:49: runtime error: index -1 out of bounds for type 'RGBTRIPLE [width]'
helpers.c:86:47: runtime error: index -1 out of bounds for type 'RGBTRIPLE [width]'
helpers.c:112:45: runtime error: index -1 out of bounds for type 'RGBTRIPLE [width]'
helpers.c:113:49: runtime error: index -1 out of bounds for type 'RGBTRIPLE [width]'
helpers.c:114:47: runtime error: index -1 out of bounds for type 'RGBTRIPLE [width]'
UndefinedBehaviorSanitizer:DEADLYSIGNAL
==4657==ERROR: UndefinedBehaviorSanitizer: SEGV on unknown address 0x7fd1249a490a (pc 0x00000042b7ea bp 0x7ffd589ca4f0 sp 0x7ffd589c90f0 T4657)
==4657==The signal is caused by a READ memory access.
#0 0x42b7e9 (/home/ubuntu/pset4/filter/filter+0x42b7e9)
#1 0x422ed2 (/home/ubuntu/pset4/filter/filter+0x422ed2)
#2 0x7fd123897b96 (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
#3 0x402d69 (/home/ubuntu/pset4/filter/filter+0x402d69)
for me it seems like the code isn't really solving the problem. It fails right out of the first iteration. because i
and j
value becomes negative, thus not really serving the intention of checking the nearby pixels' existence.
Could you share a point or two about what should be done here to better find out how the program should detect the surrounding pixels?
In C, non-zero considered as true, j-1 at j=0 is -1 true.
void blur(int height, int width, RGBTRIPLE image[height][width])
{
int red;
int green;
int blue;
int counter = 0;
RGBTRIPLE **new_image = (RGBTRIPLE**) malloc(sizeof(RGBTRIPLE*)*height);
for(int i=0;i<height;i++)
new_image[i]=((RGBTRIPLE*) malloc(sizeof(RGBTRIPLE)*width);
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
red=green=blue=0;
counter=0;
if (i + 1 <height && j - 1 >=0)
{
red += image[i][j].rgbtRed + image[i + 1][j - 1].rgbtRed;
green += image[i][j].rgbtGreen + image[i + 1][j - 1].rgbtGreen;
blue += image[i][j].rgbtBlue + image[i + 1][j - 1].rgbtBlue;
counter++;
}
if (j + 1<width)
{
red += image[i][j].rgbtRed + image[i][j + 1].rgbtRed;
green += image[i][j].rgbtGreen + image[i][j + 1].rgbtGreen;
blue += image[i][j].rgbtBlue + image[i][j + 1].rgbtBlue;
counter++;
}
if (i + 1 <height && j + 1 <width)
{
red += image[i][j].rgbtRed + image[i + 1][j + 1].rgbtRed;
green += image[i][j].rgbtGreen + image[i + 1][j + 1].rgbtGreen;
blue += image[i][j].rgbtBlue + image[i + 1][j + 1].rgbtBlue;
counter++;
}
if (i + 1<height)
{
red += image[i][j].rgbtRed + image[i + 1][j].rgbtRed;
green += image[i][j].rgbtGreen + image[i + 1][j].rgbtGreen;
blue += image[i][j].rgbtBlue + image[i + 1][j].rgbtBlue;
counter++;
}
if (j - 1>=0)
{
red += image[i][j].rgbtRed + image[i][j - 1].rgbtRed;
green += image[i][j].rgbtGreen + image[i][j - 1].rgbtGreen;
blue += image[i][j].rgbtBlue + image[i][j - 1].rgbtBlue;
counter++;
}
if (i - 1>=0)
{
red += image[i][j].rgbtRed + image[i - 1][j].rgbtRed;
green += image[i][j].rgbtGreen + image[i - 1][j].rgbtGreen;
blue += image[i][j].rgbtBlue + image[i - 1][j].rgbtBlue;
counter++;
}
new_image[i][j].rgbtRed = red/counter;
new_image[i][j].rgbtGreen = green/counter;
new_image[i][j].rgbtBlue = blue/counter;
}
}
return;
}