如何在不使用任何内置高斯函数的情况下高斯模糊图像?

Moe*_*oeb 54 c image-processing gaussianblur

我想使用原生高斯模糊公式来模糊我的图像.我读过这篇文章,但我不知道如何实现这一点.

如何使用公式来确定权重?

我不想使用MATLAB所具有的任何内置函数

Goz*_*Goz 129

写一个天真的高斯模糊实际上非常容易.它的完成方式与任何其他卷积滤波器完全相同.框和高斯滤波器之间的唯一区别是您使用的矩阵.

想象一下,您的图像定义如下:

 0  1  2  3  4  5  6  7  8  9
10 11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29
30 31 32 33 34 35 36 37 38 39
40 41 42 43 44 45 46 47 48 49
50 51 52 53 54 55 56 57 58 59
60 61 62 63 64 65 66 67 68 69
70 71 72 73 74 75 76 77 78 79
80 81 82 83 84 85 86 87 88 89
90 91 92 93 94 95 96 97 98 99
Run Code Online (Sandbox Code Playgroud)

3x3盒式滤波器矩阵定义如下:

0.111 0.111 0.111
0.111 0.111 0.111
0.111 0.111 0.111
Run Code Online (Sandbox Code Playgroud)

要应用高斯模糊,您可以执行以下操作:

对于像素11,您需要加载像素0,1,2,10,11,12,20,21,22.

然后,您将像素0乘以3x3模糊滤镜的左上部分.像素1由顶部中间,像素2,像素3由右上角,像素10由中间左侧等.

然后完全添加它们并将结果写入像素11.正如您所见,Pixel 11现在是其自身和周围像素的平均值.

边缘情况确实变得复杂一些.您使用什么值来表示纹理边缘的值?一种方法可以绕到另一边.这对于稍后平铺的图像看起来很好.另一种方法是将像素推入周围的地方.

因此,对于左上角,您可以将样本放置如下:

 0  0  1
 0  0  1
10 10 11
Run Code Online (Sandbox Code Playgroud)

我希望你能看到它如何很容易地扩展到大型滤波器内核(即5x5或9x9等).

高斯滤波器和盒式滤波器之间的差异是矩阵中的数字.高斯滤波器在行和列上使用高斯分布.

例如,对于任意定义的滤波器(即,这不是高斯,但可能不远)

0.1 0.8 0.1
Run Code Online (Sandbox Code Playgroud)

第一列将相同但乘以上一行的第一项.

0.01 0.8 0.1
0.08 
0.01 
Run Code Online (Sandbox Code Playgroud)

第二列是相同的,但值将乘以上面的行中的0.8(依此类推).

0.01 0.08 0.01
0.08 0.64 0.08
0.01 0.08 0.01
Run Code Online (Sandbox Code Playgroud)

将所有上述共同的的应等于1.上述过滤器和原箱式滤波器之间的差异的结果将是写入的结束像素将具有朝向中心像素中的更重的权重(即,一种是在那个位置已经).出现模糊是因为周围的像素会模糊到该像素,尽管不是那么多.使用这种滤镜可以获得模糊,但不会破坏高频率(即从像素到像素的颜色快速变化)信息.

这些过滤器可以做很多有趣的事情.您可以通过从当前像素中减去周围像素来使用这种滤镜进行边缘检测.这将只留下颜色(高频率)的巨大变化.

编辑:5x5过滤器内核的定义与上面完全相同.

例如,如果你的行0.1 0.2 0.4 0.2 0.1然后如果你在他们乘每个值通过的第一项,形成一列,然后乘以每个通过的第二项,形成第二列等等,你会用过滤结束的

0.01 0.02 0.04 0.02 0.01
0.02 0.04 0.08 0.04 0.02
0.04 0.08 0.16 0.08 0.04
0.02 0.04 0.08 0.04 0.02
0.01 0.02 0.04 0.02 0.01
Run Code Online (Sandbox Code Playgroud)

采取一些任意位置,你可以看到位置0,0简单0.1*0.1.位置0,2为0.1*0.4,位置2,2为0.4*0.4,位置1,2为0.2*0.4.

我希望能给你一个足够好的解释.

  • http://en.wikipedia.org/wiki/Gaussian_function希望有所帮助,-Tom (12认同)

Cec*_*ame 11

这是我在C#中用来计算内核的代码的伪代码.我不敢说我​​正确对待最终条件,但是:

double[] kernel = new double[radius * 2 + 1];
double twoRadiusSquaredRecip = 1.0 / (2.0 * radius * radius);
double sqrtTwoPiTimesRadiusRecip = 1.0 / (sqrt(2.0 * Math.PI) * radius);
double radiusModifier = 1.0;

int r = -radius;
for (int i = 0; i < kernel.Length; i++)
{
    double x = r * radiusModifier;
    x *= x;
    kernel[i] =
    sqrtTwoPiTimesRadiusRecip * Exp(-x * sqrtTwoPiTimesRadiusRecip);
    r++;
}

double div = Sum(kernel);
for (int i = 0; i < kernel.Length; i++)
{
    kernel[i] /= div;
}
Run Code Online (Sandbox Code Playgroud)

希望这可以提供帮助.

  • 我相信,这一行:`sqrtTwoPiTimesRadiusRecip*Exp(-x*sqrtTwoPiTimesRadiusRecip);`必须是:`sqrtTwoPiTimesRadiusRecip*Exp(-x*twoRadiusSquaredRecip);` (2认同)
  • 根本不需要乘以"sqrtTwoPiTimesRadiusRecip",因为无论如何都要规范化内核. (2认同)

Mar*_*son 9

要使用维基百科文章中讨论的过滤器内核,您需要实现(离散)卷积.这个想法是你有一个小的矩阵值(内核),你在图像中从像素到像素移动这个内核(即矩阵的中心在像素上),矩阵元素与重叠的图像相乘元素,对结果中的所有值求和,并用此总和替换旧像素值.

高斯模糊可以分为两个1D卷积(一个垂直和一个水平)而不是2D卷积,这也可以加快速度.