高斯模糊实现不完全工作
我想在c中从头开始实现高斯模糊。我有一个程序创建一个结构并加载一个.bmp文件,创建一个高斯模糊滤镜(前两个for-loops),然后将高度,宽度和实际像素信息发送给另一个应用滤镜的函数到图像(下面的4个嵌套for循环)。应用后,它会输出修改后的.bmp文件。目前它稍微有效,但它不能一直工作。我无法调整模糊的强度(所有模糊的水平看起来都一样)。它也似乎错过了图像周围像素的外边缘。高斯模糊实现不完全工作
当我创建过滤器,我使用:
double sigma = 10.0;
double r, s = 2.0 * sigma * sigma;
double sum = 0.0;
但它看起来相同的适马是否为1,10,100 - 我的理解是,它应该得到更加模糊与更大的西格玛。
创建过滤器:
// generate 5x5 kernel
for (int x = -2; x <= 2; x++)
{
for(int y = -2; y <= 2; y++)
{
r = sqrt(x*x + y*y);
gKernel[x+2][y+2] = (exp(-(r*r)/s))/(M_PI * s);
sum += gKernel[x + 2][y + 2];
}
}
// normalize the Kernel
for(int i = 0; i < 5; ++i)
for(int j = 0; j < 5; ++j)
gKernel[i][j] /= sum;
,然后应用过滤器:
for (i = 1; i < bmp->height - 1; i++)
{
for (j = 1; j < bmp->width - 1; j++)
{
sum = 0.0;
for (p = 0; p < 5; p++)
{
for (q = 0; q < 5; q++)
{
sum += bmp->pixels[(i + p) * bmp->width + j + q] * gKernel[p][q];
}
}
bmp->pixels[(i - 1) * (bmp->width) + j] = (unsigned char) sum ;
}
}
任何帮助,非常感谢!感谢您的时间。
它错过了边缘点,因为你已经告诉它这样做。它也被硬编码为宽度为5个像素的内核。
边缘始终是过滤的问题。通常最好是扩大图像,用镜像填充。然后应用没有特殊代码的滤波器来处理边缘条件。 宽*高* N * N方法非常慢。对于大型滤波器,您需要使用FFT进行滤波。这是一种更先进的技术。
鉴于电脑总是按照你告诉他们的方式做,所以我认为这是真的我告诉它错过边缘:)我只需要弄清楚如何解决它。从上面的评论中,我会看看用sigma值增加内核大小是否能解决问题 - 我没有意识到这是一个问题。我会寻找填充和FFT。谢谢你的帮助! – kab403
今天早些时候我想到了这一点 - 多亏了那些回应,你们都会有很多帮助!基本上,当我增加代码以增加内核的大小时,我增加了西格玛,我能够调整图像出现的模糊程度。我还添加了代码来处理边缘情况 - 在该笔记中,我正在使用if-else if-else语句,但我试图找出填充。
现在我有:
// generate nxn kernel
for (int i = 0; i < kSize; i++)
{
for(int j = 0; j < kSize; j++)
{
gKernel[i][j] = exp(-(i*i+j*j)/(2*sigma*sigma))/(2*M_PI*sigma*sigma);
sum += gKernel[i][j];
}
}
你能想象的所有“5的上面现在被替换成 'kSize'。当我应用滤镜时,我调整for循环从0到bmp-> width/height,然后调整我将像素置于循环体内的位置(这是if-else if-else语句进入的位置玩,尽管我会尽快改变)。再次感谢!
欢迎来到Stack Overflow。遵循SO约定使您更有可能获得帮助。请阅读如何提供一个MCVE。 https://*.com/help/mcve – Gene
当您增加西格玛时,是否增加了您的过滤器内核大小? –
否 - 你的意思是为x的西格玛生成一个x x内核,然后x + 5的x + 5内核生成一个y + 5的西格玛?我只测试了5的内核大小5.当我增加西格玛时,我应该增加这个值吗? – kab403