高斯模糊实现不完全正常

时间:2017-06-16 23:15:30

标签: c gaussian bmp

我正试图在c中从头开始实现高斯模糊。我有一个程序,它创建一个结构并加载一个.bmp文件,创建一个高斯模糊过滤器(下面的前两个for循环),然后将结构的高度,宽度和实际像素信息发送到另一个应用过滤器的函数到图像(下面的4个嵌套for循环)。应用后,它会输出修改后的.bmp文件。目前它略有作用,但它不是一直都在工作。我无法调整模糊的强度(模糊的所有级别看起来都一样)。它似乎也错过了图像周围像素的外边缘。

当我创建过滤器时,我使用:

double sigma = 10.0;
double r, s = 2.0 * sigma * sigma;
double sum = 0.0;

但是sigma是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 ;
    }
}

任何帮助非常感谢!谢谢你的时间。

2 个答案:

答案 0 :(得分:1)

它错过了边缘点,因为你告诉它这样做。它也被硬编码为宽度为5像素的内核。

边缘始终是过滤的问题。通常最好扩展图像,使用镜像填充。然后应用过滤器而不使用边缘条件的特殊代码。 宽度*高度* N * N方法非常慢。对于大滤波器,您需要使用FFT进行滤波。这是一种更先进的技术。

答案 1 :(得分:0)

我今天早些时候想到了这一点 - 感谢那些回复的人,所有人都得到了很多帮助!基本上,当我添加代码以增加内核的大小时,我增加了sigma,我能够调整图像的模糊程度。我还添加了代码来处理边缘情况 - 在那个注释中,我当前正在使用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]; 
    }
}

你可以想象上面的所有&#39; 5现在都用&#39; kSize&#39;替换。当我应用滤镜时,我调整for循环从0到bmp-> gt; width / height然后调整我将像素放在循环体内的位置(这是if-else if-else语句来的地方虽然我很快就会改变这种状态,但还是会发挥作用。再次感谢!