前两个不是那么困难,但是第三个使我发疯。模糊滤波器必须计算某些像素组的rgb值的平均值,以替换居中像素的值。想象一下一个3x3的网格,其中中心的像素必须使用周围8个像素的平均值和中心像素本身的rgb值进行操作。
到目前为止我所做的是:
// Blur image
void blur(int height, int width, RGBTRIPLE image[height][width])
{
int n;
int m;
int averageRed;
int averageBlue;
int averageGreen;
//For each row..
for (int i = 0; i < height; i++)
{
//..and then for each pixel in that row...
for (int j = 0; j < width; j++)
{
//...if i and j equal 0...
if (i == 0 && j == 0)
{
for (m = i; m <= 1; m++)
{
for (n = j; n <= 1; n++)
{
averageRed = averageRed + image[m][n].rgbtRed;
averageBlue = averageBlue + image[m][n].rgbtBlue;
averageGreen = averageGreen + image[m][n].rgbtGreen;
printf("%i\n", averageRed);
printf("%i\n", averageBlue);
printf("%i\n", averageGreen);
}
}
image[i][j].rgbtRed = round((float)averageRed / 4);
image[i][j].rgbtBlue = round((float)averageBlue / 4);
image[i][j].rgbtGreen = round((float)averageGreen / 4);
printf("%i\n", image[i][j].rgbtRed);
printf("%i\n", image[i][j].rgbtBlue);
printf("%i\n", image[i][j].rgbtGreen);
}
//If i equals 0 and j is greater than 0...
else if (i == 0 && j > 0)
{
//..take the line that equals i..
for (m = i; m <= 1; m++)
{
//..and take from each pixel ot that line...
for (n = j - 1; n <= 1; n++)
{
//..the color values and add them to the average-variables
averageRed = averageRed + image[m][n].rgbtRed;
averageBlue = averageBlue + image[m][n].rgbtBlue;
averageGreen = averageGreen + image[m][n].rgbtGreen;
}
}
//Set the current pixel values to the averages
image[i][j].rgbtRed = round((float)averageRed / 6);
image[i][j].rgbtBlue = round((float)averageBlue / 6);
image[i][j].rgbtGreen = round((float)averageGreen / 6);
printf("%i\n", image[i][j].rgbtRed);
printf("%i\n", image[i][j].rgbtBlue);
printf("%i\n", image[i][j].rgbtGreen);
}
else if (i > 0 && j == 0)
{
for (m = i - 1; m <= 1; m++)
{
for (n = j; n <= 1; n++)
{
averageRed = averageRed + image[m][n].rgbtRed;
averageBlue = averageBlue + image[m][n].rgbtBlue;
averageGreen = averageGreen + image[m][n].rgbtGreen;
}
}
image[i][j].rgbtRed = round((float)averageRed / 6);
image[i][j].rgbtBlue = round((float)averageBlue / 6);
image[i][j].rgbtGreen = round((float)averageGreen / 6);
}
else if (i > 0 && j > 0 )
{
// ..take every line from i - 1 to i + 1...
for (m = i - 1; m <= 1; m++)
{
//...and in each line take every pixel from j - 1 to j + 1...
for (n = j - 1; n <= 1; n++)
{
//...and add the RGB value to average-variables
averageRed = averageRed + image[m][n].rgbtRed;
averageBlue = averageBlue + image[m][n].rgbtBlue;
averageGreen = averageGreen + image[m][n].rgbtGreen;
}
}
//Set current value to the rounded average
image[i][j].rgbtRed = ((float)averageRed / 9);
image[i][j].rgbtBlue = ((float)averageBlue / 9);
image[i][j].rgbtGreen = ((float)averageGreen / 9);
}
}
}
return;
}
编译时没有任何抱怨,但是结果有点奇怪(尤其是前四个块)-Test.bmp ist只是一个55px x 55px黑色/白色bmp文件:
> ~/pset4/filter/ $ ./filter -b images/test.bmp blur.bmp0 38118032 0 0
> 38118032 0 0 38118032 0 0 38118032 0 helpers.c:93:40: runtime error:
> 9.52951e+06 is outside the range of representable values of type 'unsigned char' 0 164 0 helpers.c:120:40: runtime error: 6.35303e+06
> is outside the range of representable values of type 'unsigned char' 0
> 137 0 0 160 0 0 160 0 0 160 0 0 160 0 0 160 0 0 160 0 0 160 0 0 160 0
> 0 160 0 0 160 0 0 160 0 0 160 0 0 160 0 0 160 0 0 160 0 0 160 0 0 160
> 0 0 160 0 0 160 0 0 160 0 0 160 0 0 160 0 0 160 0 0 160 0 0 160 0 0
> 160 0 0 160 0 0 160 0 0 160 0 0 160 0 0 160 0 0 160 0 0 160 0 0 160 0
> 0 160 0 0 160 0 0 160 0 0 160 0 0 160 0 0 160 0 0 160 0 0 160 0 0 160
> 0 0 160 0 0 160 0 0 160 0 0 160 0 0 160 0 0 160 0 0 160 0 0 160 0 0
> 160 0 0 160 0 helpers.c:142:40: runtime error: 6.35311e+06 is outside
> the range of representable values of type 'unsigned char'
> helpers.c:167:40: runtime error: 4.23546e+06 is outside the range of
> representable values of type 'unsigned char' ~/pset4/filter/ $
非常感谢您提供任何建议!
Greetz
除了其他人已指出的其他问题,您可能需要进行饱和度数学。
这是因为rgbt*
(例如rgbtRed
)是byte,所以该值可能会被错误地剪切。
您正在做:
image[i][j].rgbtRed = round((float)averageRed / 6);
可以改写为:
averageRed = round((float)averageRed / 6);
image[i][j].rgbtRed = averageRed;
但是,如果(例如)averageRed
为256,则rgbtRed
最终将为1 [因为对image
的分配是[有效]:
image[i][j].rgbtRed = averageRed & 0xFF;
因此,您存储的不是黑色,而是存储鲜红色。最终将需要为255,即“饱和”最大颜色值。
因此,要解决此问题,请执行:
averageRed = round((float)averageRed / 6);
if (averageRed > 255)
averageRed = 255;
image[i][j].rgbtRed = averageRed;