图像高斯滤波的最佳sigma值是多少?

16

在对图像应用高斯模糊时,通常需要指定一个参数 sigma(例如 Matlab 和 ImageJ)。

如何确定 sigma 的值?有没有数学方法来找到最佳的 sigma 值?在我的情况下,我有一些在图像中与背景相比较亮的物体,我需要通过计算找到它们。我将应用高斯滤波器来使这些物体的中心更加明亮,这有助于更容易地找到它们。那么,如何确定这个问题的最佳 sigma 值呢?

4个回答

22

针对您的情况,没有一个公式可以为您确定最佳的sigma值; 最优的sigma值将取决于图像因素-主要是图像的分辨率和其中对象的大小(以像素为单位)。

此外,请注意,高斯滤波器实际上并不是用来增强任何内容的;您可能需要研究最大对比度技术-听起来像是一些简单的直方图拉伸技术可以很好地解决这个问题。

编辑: 更多解释-sigma基本上控制着您的核函数要变得多“胖”;更高的sigma值会使模糊半径更大。由于您正在处理图像,更大的sigma还会迫使您使用较大的核矩阵来捕获足够的函数能量。对于您的特定情况,您希望您的核足够大以覆盖大部分对象(以便它们被模糊),但不能太大,以至于它开始同时重叠多个相邻对象-因此,物体分离也是一个重要因素。

由于您提到了MATLAB-您可以使用fspecial('gaussian', hsize, sigma)函数查看具有不同参数的各种高斯核。其中hsize是核的大小,sigma是sigma值。尝试改变这些参数以查看其如何变化。


@tzaman:你能详细说明一下最佳sigma如何取决于图像的分辨率和物体在像素中的大小吗?或者如果可以的话,给我指点一下读物。那正是我要找的。另外,我说错了,我想说的是我希望我的物体中心相对于其他部分要更亮些。 - Tony Stark
@hatorade:我扩展了我的回答,希望它能澄清事情。 - tzaman
@tzaman:在一个网站上(http://imaging.mrc-cbu.cam.ac.uk/imaging/PrinciplesSmoothing)我读到 Full Width at Half Maximum (FWHM) 的测量有一个方程。这个概念是否适用于核函数?也就是说,在 ImageJ 或 Matlab 中,核函数的 "FWHM" 是否与 sigma 以相同的方式相关?我之所以问这个问题,是因为通常参数是核函数的尺寸和 sigma,但我一直在读到 sigma 影响核函数的大小... - Tony Stark
2
@hatorade:是的-本质上,FWHM是衡量函数“展开”的一种方式;因此,对于更高的sigma,它将更大。例如,您可以使用它来帮助确定给定内核的矩阵大小应该是多少。虽然在某种意义上,您可以单独选择维度和sigma,但实际上,维度必须与sigma相结合才有意义-它需要足够大以保留曲线的形状;如果您截断得太多,它就不再是高斯模糊,而更像是简单的平均滤波器。 - tzaman
@tzaman:没错。你知道正态分布曲线底部宽度的方程式吗?而不是在半最大值处的宽度?本质上,我知道我想要核的大小,但我不知道如何从中计算出sigma(因此从核大小-> sigma而不是从sigma-> kernel size)。 - Tony Stark
@hatorade:高斯函数本质上是无限的,尽管随着距离的增加它们会下降到可以忽略的值,因此基底宽度没有“极限”。两倍的FWHM或类似的东西听起来很合理。此外,即使在特定的内核大小下,您也可以有意义地改变sigma(对于任何给定的内核,没有“最佳sigma”)-将其视为将高斯滤波器乘以这些维度的框滤波器。 - tzaman

8

我通常使用这个公式作为经验法则,如果k是内核的大小,那么sigma=(k-1)/6。这是因为高斯概率密度函数 99百分位点长度为 6sigma


10
这是正确的,但我建议采用相反的方法:首先确定最佳的sigma值,然后找到内核大小,使其包含6 sigma。这是因为内核大小是离散量(以2的步长递增),而sigma是连续变量,因此可以进行更精细的调整。k=2*ceil(3*sigma)+1 - Cris Luengo
1
@CrisLuengo 很有道理。 - Operator77

1
你需要找到一个函数 G 的最小值/最大值,使得 G(X,sigma)成立,其中 X 是您的观察集合(在这种情况下,是您图像的灰度值)。此函数可以是任何维持图像强度“顺序”的东西,例如可以使用图像的一阶导数(作为G)来实现。
fil = fspecial('sobel');
im = imfilter(I,fil);
imagesc(im);
colormap = gray;

这个操作可以给你图像的一阶导数结果,现在你想通过最大化G(X,sigma)来找到最大的sigma值,这意味着你需要尝试几个sigma值(比如按递增顺序),直到找到一个使得G最大的sigma值。这也可以用二阶导数来实现。


0

假设内核的中心值为1,保证外层值小于一个限制(例如1/100)的维数如下:

double limit = 1.0 / 100.0;
size = static_cast<int>(2 * std::ceil(sqrt(-2.0 * sigma * sigma * log(limit))));
if (size % 2 == 0)
{
    size++;
}       

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接