我已经为此工作了两周,但无济于事。我认为逻辑和实现是合理的,但是除了使角落像素模糊之外,它没有通过所有测试。
我的逻辑:将原始像素文件图像中的每个像素复制到相同的像素,计算每个相邻像素中RGB值的平均值(如果存在),然后将其应用于原始图像。我的实现通过嵌套循环扫描每个像素的上一行,下一行和下一行。我知道这不是最简洁的实现方式-我对此并不陌生。
这里是一个此类错误的示例:
:(模糊错误地过滤3x3图像
预期输出
70 85 95
80 95 105
90 105 115
117 130 140
127140149
137 150 159
163178188
170185194
178193201
我的结果:
实际输出
70 85 95
90 106 116
103 119 129
135150160
145 160169
155169178
175 188 197
178191200
180193201
这是我的代码(用C语言编写:):
// Blur image
void blur(int height, int width, RGBTRIPLE image[height][width])
{
RGBTRIPLE imageCopy[height][width];
//assign new image
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
imageCopy[i][j] = image[i][j];
}
}
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
int red = 0;
int green = 0;
int blue = 0;
float pixelCount = 0.00;
//scan top row
for (int k = -1; k < 2; k++)
{
if ((i - 1) >= 0 && (j + k) >= 0 && (j + k) < width)
{
red += imageCopy[i - 1][j + k].rgbtRed;
green += imageCopy[i - 1][j + k].rgbtGreen;
blue += imageCopy[i - 1][j + k].rgbtBlue;
pixelCount++;
}
}
//scan same row
for (int m = -1; m < 2; m++)
{
if ((j + m) >= 0 && (j + m) < width)
{
red += imageCopy[i][j + m].rgbtRed;
green += imageCopy[i][j + m].rgbtGreen;
blue += imageCopy[i][j + m].rgbtBlue;
pixelCount++;
}
}
//scan below row
for (int n = -1; n < 2; n++)
{
if ((i + 1) < height && (j + n) >= 0 && (j + n) < width)
{
red += imageCopy[i + 1][j + n].rgbtRed;
green += imageCopy[i + 1][j + n].rgbtGreen;
blue += imageCopy[i + 1][j + n].rgbtBlue;
pixelCount++;
}
}
// find averages
imageCopy[i][j].rgbtRed = round(red / pixelCount);
imageCopy[i][j].rgbtGreen = round(green / pixelCount);
imageCopy[i][j].rgbtBlue = round(blue / pixelCount);
}
}
// assign back to original image
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
image[i][j] = imageCopy[i][j];
}
}
return;
}
提前感谢。
确定,我找到了[[问题。
您为每个像素计算一个新的“模糊”值,那里的逻辑似乎很好。最后,您要做的就是用这段代码为像素分配“新的模糊值”。imageCopy[i][j].rgbtRed = round(red / pixelCount);
imageCopy[i][j].rgbtGreen = round(green / pixelCount);
imageCopy[i][j].rgbtBlue = round(blue / pixelCount);
这不行,因为您对已更改的图像应用了“模糊”过滤。因此,您要做的实际上是将一个像素更改为一个模糊像素,然后对于邻域像素,使用其旁边的“模糊”像素进行计算,这是错误的。解决方案;
imageCopy
不应在计算期间更改,因为所有模糊计算均应在“原始图像”上进行。在每个像素的末尾,您应将值直接传递给image
。如下所示,将imageCopy
替换为image
。image[i][j].rgbtRed = round(red / pixelCount);
image[i][j].rgbtGreen = round(green / pixelCount);
image[i][j].rgbtBlue = round(blue / pixelCount);
并从代码中删除此for循环。
for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { image[i][j] = imageCopy[i][j]; } }