I'm working on a box blur algorithm, that I have to implement for one of the course's exercise. Basically, I need to take an image and blur each pixel using this algo (below, the course's description).
"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.
https://i.stack.imgur.com/83CjW.jpg
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, I tried to implement my solution creating an extended array where all the rows and columns around the image should have the color values set to 0. This way, I didn't need to think around about edge, corner cases.
// Blur image
void blur(int height, int width, RGBTRIPLE image[height][width])
{
int red = 0, green = 0, blue = 0;
float counter = 0.0;
int exheight = height + 2;
int exwidth = width + 2;
// Creates an extended array to make the implementation of the box blur algorithm easier
RGBTRIPLE eximg[exheight][exwidth];
for (int i = 0; i < exheight; i++) {
for (int j = 0; j < exwidth; j++) {
if (i == 0 || i == height + 1) {
eximg[i][j].rgbtRed = 0;
eximg[i][j].rgbtGreen = 0;
eximg[i][j].rgbtBlue = 0;
} // Sets the '0' color value for the pixels in the extended row and column
if (j == 0 || j == width + 1) {
eximg[i][j].rgbtRed = 0;
eximg[i][j].rgbtGreen = 0;
eximg[i][j].rgbtBlue = 0;
}
else if (i > 0) {
eximg[i][j].rgbtRed = image[i - 1][j - 1].rgbtRed;
eximg[i][j].rgbtGreen = image[i - 1][j - 1].rgbtGreen; // Configure the layout for the extended array
eximg[i][j].rgbtBlue = image[i - 1][j - 1].rgbtBlue;
}
}
}
// Configure the blur effect for each pixel
for (int i = 1; i < exheight; i++) {
for (int j = 1; j < exwidth; j++) {
red = 0;
green = 0;
blue = 0;
counter = 0.0;
// Sets the counter for edge pixels
if (i - 1 == 0 && (j - 1 == 0 || j - 1 == 3)) {
counter = 4.0;
}
// Sets the counter for corner pixels
else if ((i == 1 && (j == 2 || j == 3)) || (i == 4 && (j == 2 || j == 3)) || (j == 1 && (i == 2 || i == 3)) || (j == 4 && (i == 2 || i == 3))) {
counter = 6.0;
}
// Sets the counter for middle pixels
else {
counter = 9.0;
}
// Calculation for the pixels
red = round((eximg[i][j].rgbtRed + eximg[i][j - 1].rgbtRed + eximg[i][j + 1].rgbtRed + eximg[i - 1][j - 1].rgbtRed + eximg[i - 1][j].rgbtRed + eximg[i - 1][j + 1].rgbtRed + eximg[i + 1][j - 1].rgbtRed + eximg[i + 1][j].rgbtRed + eximg[i + 1][j + 1].rgbtRed) / counter);
green = round((eximg[i][j].rgbtGreen + eximg[i][j - 1].rgbtGreen + eximg[i][j + 1].rgbtGreen + eximg[i - 1][j - 1].rgbtGreen + eximg[i - 1][j].rgbtGreen + eximg[i - 1][j + 1].rgbtGreen + eximg[i + 1][j - 1].rgbtGreen + eximg[i + 1][j].rgbtGreen + eximg[i + 1][j + 1].rgbtGreen) / counter);
blue = round((eximg[i][j].rgbtBlue + eximg[i][j - 1].rgbtBlue + eximg[i][j + 1].rgbtBlue + eximg[i - 1][j - 1].rgbtBlue + eximg[i - 1][j].rgbtBlue + eximg[i - 1][j + 1].rgbtBlue + eximg[i + 1][j - 1].rgbtBlue + eximg[i + 1][j].rgbtBlue + eximg[i + 1][j + 1].rgbtBlue) / counter);
// Applies the changes to the original image array
image[i - 1][j - 1].rgbtRed = red;
image[i - 1][j - 1].rgbtGreen = green;
image[i - 1][j - 1].rgbtBlue = blue;
}
}
return;
}
Then, I checked my output with a 4x4 image. This is the expected output: 70 85 95 80 95 105 100 115 125 110 125 135 113 126 136 123 136 145 142 155 163 152 165 173 113 119 136 143 151 164 156 166 171 180 190 194 113 112 132 155 156 171 169 174 177 203 207 209
And this is my output: 70 85 95 80 95 105 100 115 125 110 125 135 113 126 136 123 136 145 142 155 163 152 165 173 113 119 136 143 151 164 156 166 171 180 190 194 78 78 58 239 198 211 253 0 2 118 119 147
Everything ok, only the last row is incorrect. Can someone help me to find what's the error?