Image processing 高斯模糊中二维掩模到一维的转换
我正在尝试实现高斯模糊。我已经使用上提供的2d函数计算了遮罩。我现在有一个2d矩阵。我知道为了提高运行时间,可以避免使用标准卷积方法,因为高斯函数是可分离的。换句话说,正如上面所说,“在高斯模糊的情况下,它分解为两个一维操作” 已经很有帮助了,但是,我不知道如何从现有的2d蒙版中获得1d蒙版。例如,将图3中的2d遮罩转换为图4中的1d遮罩。如何进行这种转换 [编辑] 首先计算1d遮罩,然后将其应用于x方向,然后应用于y方向,是否足够 [编辑2] 我发现,是的,一个人可以简单地生成一个一维掩模,并在x和y方向上使用它。然而,问题是当我应用高斯滤波器时,结果图像的质量 我假设在计算掩模的点积和原始图像的选定部分时,需要进行一些操作。是什么导致生成的图像是这样的 [编辑] 除了@Jeremie Miserez的回答之外,这非常有帮助。如果你想知道这是如何实现的,它也有代码。关于可分离卷积的内容应该会有点清楚 我最近不得不这么做,所以这里是这样的:作为一个例子,我们使用一个基于二维高斯分布的内核,标准偏差为0.85。我们需要一个3x3内核(Matlab代码) 请注意,所有条目的总和为1,即如果将其用作过滤器,图像的亮度不会改变: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] 我发现,是的,一个人可以简单地生成一个一维掩模,并
>> 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