I spent several day trying to figure out what's wrong with this function. It actually compile fine but it blurs the image in the wrong way. I believe maybe my numbers or formulas are wrong but after checking it again and again for several hours I cannot figure out what s wrong.
The exercise wants you to blur an image using a 3*3 blur box so adding up the RGB values of the blur box and dividing them by the valid blur box pixels (the ones in side the image boundaries).Then assigning the 'blurred' values to the image.
In my blurred image the blur does not allow to distinguish any figure in the picture. I checked other blur function answers and tried to make and re-make the code from scratch with different variations but nothing seems to work. The code below it seems to me it s the closer to the right solution. Any help would be very much appreciate. Sorry for any mistake in my english
// Blur image
void blur(int height, int width, RGBTRIPLE image[height][width])
{ // create image copy for holding modifies RGB values
RGBTRIPLE copy[height][width];
for(int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
copy[i][j] = image[i][j];
}
}
// setting variable for holding sum of blur box RGB values
float blurred = 0.0;
float blurgreen = 0.0;
float blurblue = 0.0;
// setting counter for valid blur box pixels
float validpixels = 0.0;
// looping through image rows
for( int i = 0; i < height; i++)
{ // looping through image columns
for(int j = 0; j < width; j++)
{ // looping through blur box rows
for(int r = -1; r < 2; r++)
{ //looping through blur box columns
for(int c = -1; c < 2; c++)
{ // counting only valid blur-box pixels(inside image boundaries)
if(i + c >= 0 && j + r >= 0 && i + c < height && j + r < width)
{ // storing total of blur box RGB values
blurred += copy[i + c][j + r].rgbtRed;
blurgreen += copy[i + c][j + r].rgbtGreen;
blurblue += copy[i + c][j + r].rgbtBlue;
// counting valid pixels total
validpixels ++;
}
}
}
// calculate RGB blurred values and assigning them to image copy
copy[i][j].rgbtRed = round(blurred / validpixels);
copy[i][j].rgbtGreen = round(blurgreen / validpixels);
copy[i][j].rgbtBlue = round(blurblue / validpixels);
}
}
//giving blur values back to image
for(int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
image[i][j].rgbtRed = copy[i][j].rgbtRed;
image[i][j].rgbtGreen = copy[i][j].rgbtGreen;
image[i][j].rgbtBlue = copy[i][j].rgbtBlue;
}
}
return;
}
You have 2 main issues:
blur*
variables and also the counter for each pixel. Otherwise you keep summing up more and more pixels. That will basically create an average of the whole image when you get to the end.Not an issue but could be improved:
float
in your programs. Unless you have some very strict limitations in memory or computing power, you should always use double
for floating point numbers.round
by lround
. Or use integer arithmetics all the way as shown in Chux's answer.The fixes are marked in the code using //####
// Blur image
void blur(int height, int width, RGBTRIPLE image[height][width])
{ // create image copy for holding modifies RGB values
RGBTRIPLE copy[height][width];
for(int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
copy[i][j] = image[i][j];
}
}
// looping through image rows
for( int i = 0; i < height; i++)
{ // looping through image columns
for(int j = 0; j < width; j++)
{ // looping through blur box rows
// setting variable for holding sum of blur box RGB values
//#### Initialize your blurring variables for each pixel you are visiting.
//#### Always use double instead of float except you have specific requirements.
double blurred = 0.0;
double blurgreen = 0.0;
double blurblue = 0.0;
// setting counter for valid blur box pixels
//#### Also re-initialize counter for each pixel
//#### Counters are normally integers, no floating point numbers
size_t validpixels = 0;
for(int r = -1; r < 2; r++)
{ //looping through blur box columns
for(int c = -1; c < 2; c++)
{ // counting only valid blur-box pixels(inside image boundaries)
if(i + c >= 0 && j + r >= 0 && i + c < height && j + r < width)
{ // storing total of blur box RGB values
blurred += copy[i + c][j + r].rgbtRed;
blurgreen += copy[i + c][j + r].rgbtGreen;
blurblue += copy[i + c][j + r].rgbtBlue;
// counting valid pixels total
validpixels ++;
}
}
}
// calculate RGB blurred values and assigning them to image copy
//#### No! Don't store in the copy again. This will disturb
//#### calculation of the other pixels.
image[i][j].rgbtRed = lround(blurred / validpixels);
image[i][j].rgbtGreen = lround(blurgreen / validpixels);
image[i][j].rgbtBlue = lround(blurblue / validpixels);
}
}
//giving blur values back to image
//#### No! Copying again is not required. Results were stored there already
return;
}