Image processing 高斯模糊中二维掩模到一维的转换

Image processing 高斯模糊中二维掩模到一维的转换,image-processing,linear-algebra,gaussian,convolution,Image Processing,Linear Algebra,Gaussian,Convolution,我正在尝试实现高斯模糊。我已经使用上提供的2d函数计算了遮罩。我现在有一个2d矩阵。我知道为了提高运行时间,可以避免使用标准卷积方法,因为高斯函数是可分离的。换句话说,正如上面所说,“在高斯模糊的情况下,它分解为两个一维操作” 已经很有帮助了,但是,我不知道如何从现有的2d蒙版中获得1d蒙版。例如,将图3中的2d遮罩转换为图4中的1d遮罩。如何进行这种转换 [编辑] 首先计算1d遮罩,然后将其应用于x方向,然后应用于y方向,是否足够 [编辑2] 我发现,是的,一个人可以简单地生成一个一维掩模,并

我正在尝试实现高斯模糊。我已经使用上提供的2d函数计算了遮罩。我现在有一个2d矩阵。我知道为了提高运行时间,可以避免使用标准卷积方法,因为高斯函数是可分离的。换句话说,正如上面所说,“在高斯模糊的情况下,它分解为两个一维操作”

已经很有帮助了,但是,我不知道如何从现有的2d蒙版中获得1d蒙版。例如,将图3中的2d遮罩转换为图4中的1d遮罩。如何进行这种转换

[编辑]

首先计算1d遮罩,然后将其应用于x方向,然后应用于y方向,是否足够

[编辑2]

我发现,是的,一个人可以简单地生成一个一维掩模,并在x和y方向上使用它。然而,问题是当我应用高斯滤波器时,结果图像的质量

我假设在计算掩模的点积和原始图像的选定部分时,需要进行一些操作。是什么导致生成的图像是这样的

[编辑]

除了@Jeremie Miserez的回答之外,这非常有帮助。如果你想知道这是如何实现的,它也有代码。

关于可分离卷积的内容应该会有点清楚

我最近不得不这么做,所以这里是这样的:作为一个例子,我们使用一个基于二维高斯分布的内核,标准偏差为0.85。我们需要一个3x3内核(Matlab代码)

请注意,所有条目的总和为1,即如果将其用作过滤器,图像的亮度不会改变:

>> sum(sum(h))

ans =
     1
还请注意,值为1,因此内核实际上是可分离的(两个向量
h1
h2
,当相乘时将导致
h
h1*h2=h

太好了,我们可以继续了。请注意,如果秩大于1,仍然可以得到近似值,但可能需要使用不同的技术(请参见末尾的链接)

在不深入细节的情况下,我们使用
svd
函数。这是一个标准函数,计算
U*S*V'=h
,在许多数学库中都可用

>> [U,S,V] = svd(h)

U =
   -0.4085    0.9116   -0.0445
   -0.8162   -0.3867   -0.4292
   -0.4085   -0.1390    0.9021

S =
    0.3749         0         0
         0    0.0000         0
         0         0    0.0000

V =
   -0.4085   -0.3497   -0.8431
   -0.8162    0.5534    0.1660
   -0.4085   -0.7559    0.5115
我们现在知道
U*S*V'=h
V'
V
的转置)。现在,对于秩1矩阵,
S
应该只有1个奇异值,其余的应该是0(有关更多信息,请参阅本答案末尾的讨论)

所以我们现在需要的是
(h1)*(h2)=h
。我们可以将
S
分成两个不同的值,这样
s1*s2=S
。因此我们得到:
U*s1*s2*V'=h
,然后
(U*s1)*(s2*V')=h

您可以选择如何拆分
S
,但使用平方根将
S
h1
h2
之间等分:

>> h1 = U*sqrt(S)

h1 =
   -0.2501    0.0000   -0.0000
   -0.4997   -0.0000   -0.0000
   -0.2501   -0.0000    0.0000

>> h2 = sqrt(S)*V'

h2 =
   -0.2501   -0.4997   -0.2501
   -0.0000    0.0000   -0.0000
   -0.0000    0.0000    0.0000
请注意,我们不需要额外的带零的行/列,因此我们可以这样做:

>> h1 = U(:,1)*sqrt(S(1,1))

h1 =
   -0.2501
   -0.4997
   -0.2501

>> h2 = sqrt(S(1,1))*V(:,1)'

h2 =
   -0.2501   -0.4997   -0.2501
请注意,减号相互抵消,因此如果愿意,也可以从
h1
h2
中删除减号:

h1 =
    0.2501
    0.4997
    0.2501
h2 =
    0.2501    0.4997    0.2501

>> h1*h2

ans =
    0.0626    0.1250    0.0626
    0.1250    0.2497    0.1250
    0.0626    0.1250    0.0626
这与我们之前的情况(几乎)相同:

>> h1*h2 - h

ans =
   1.0e-16 *
         0    0.2776   -0.1388
         0    0.5551   -0.2776
         0    0.2776   -0.1388
请注意,机器精度
eps
仅为:

>> eps
ans =
   2.2204e-16

所以误差很小,在这种情况下是由于不精确。如果您有任何比这更大的错误,您很可能只是忽略剩余的奇异值,然后计算
h
的秩1近似值。在这种情况下,您可能需要研究其他选项以获得更好的近似值,例如or。

我的答案解释了如何获得数字。然而,从您的图片来看,它更像是一个实现问题。尝试在Matlab中或首先(
imfilter
conv2
)测试滤波器,以确保数字不是问题(倍频程是免费的)。还要确保2d内核的总和为1,否则它将无法工作
>> h1*h2 - h

ans =
   1.0e-16 *
         0    0.2776   -0.1388
         0    0.5551   -0.2776
         0    0.2776   -0.1388
>> eps
ans =
   2.2204e-16