Python 中的 Matlab imgaussfilt 等价物
Matlab's imgaussfilt equivalent in Python
我试图在 Python 中复制 Matlab 的 imgaussfilter 行为,但我一直无法重现结果。文档没有太大帮助,因为没有解释到底做了什么(例如,该函数与 fspecial 有何不同,或者它与 Octave 的 imsmooth(以高斯作为参数)有何不同)。
Matlab代码
imgaussfilt(image,sigma)
有输出
[[-0.02936392 -0.03168419 -0.0343706 ... 0.03136455 0.02864487
0.02585145]
[-0.03212093 -0.0347433 -0.03775943 ... 0.03507484 0.03209807
0.02906134]
[-0.03512981 -0.03808864 -0.04147075 ... 0.03873834 0.03549163
0.03219311]
...
[-0.07713804 -0.08337475 -0.08975262 ... -0.04314206 -0.03945251
-0.03606256]
[-0.07145457 -0.07714807 -0.08297654 ... -0.03986635 -0.03641579
-0.03323718]
[-0.06605107 -0.07122191 -0.07651892 ... -0.03684535 -0.03362917
-0.03065128]]
我最接近 Python 的是:
Python
skimage.filters.gaussian(image, sigma=s,mode = 'nearest',truncate=2.0)
有输出
[[-0.02936397 -0.03168425 -0.03437067 ... 0.03136461 0.02864492
0.0258515 ]
[-0.03212099 -0.03474336 -0.03775951 ... 0.03507491 0.03209814
0.0290614 ]
[-0.03512988 -0.03808872 -0.04147083 ... 0.03873842 0.03549169
0.03219317]
...
[-0.07713819 -0.08337491 -0.08975279 ... -0.04314214 -0.03945259
-0.03606263]
[-0.07145471 -0.07714821 -0.0829767 ... -0.03986643 -0.03641586
-0.03323725]
[-0.06605119 -0.07122205 -0.07651907 ... -0.03684542 -0.03362923
-0.03065134]]
这是相似但不完全相同的结果。有没有更好地近似它的方法?我需要更改其中一个参数吗?
编辑:
如果您正在寻找使用 OpenCV 的近似值,@avisionx 在解决方案中提供了一个很好的起点。
这有多种可能的原因。由于 Matlab 不是开源软件,因此无法知道确切原因,但我们可以进行一些有根据的猜测。
关于什么 Gaussian filtering is doing: it replaces every pixel with a weighted sum of its neighbors. The weighting is determined by the Gaussian probability density function, 确切 权重由 sigma 决定,但也由 truncate
参数决定,您可以在 [=11] 中看到=] 文档。这个参数是必需的,因为从技术上讲,高斯函数永远不会衰减到零,它只是随着距离变得无穷大而接近零,所以 "perfect" 高斯模糊需要对无限数量的相邻像素求和,这是不可能的.因此,该函数需要决定距离零有多远才能停止求和。
另一个复杂因素是高斯模糊是 separable, which means that you can do a 2D (or nD) blur by blurring separately along each axis in sequence, which can reduce computing costs. Separability affects the order of computation, and floating point computation is not exact,因此如果 Matlab 和 Python 以不同的顺序执行操作,您会得到略有不同的结果。
即使您以完全相同的顺序过滤轴(您可以通过例如转置 Python 中的图像,过滤,然后将其转回),底层的低级数组计算库可能以不同的顺序对数组求和,这又会改变确切的结果。
简而言之,您所看到的差异的一些可能原因:
- 截断不同
- 不同的实现(是否分离过滤器)
- 轴的不同处理顺序
- 低级和的不同排序
可能没有办法解决这些问题,最后我的建议反映了 Cris Luengo 的评论:您的结果可能不应该依赖于比六位有效数字更精确的值。 Matlab 和 Python 之间的精确匹配在这里将毫无意义,因为两者都不能保证相对于高斯滤波器的理论值的完美准确性。两者都是近似值,完全匹配仅意味着您在两者中产生相同的近似值误差。
我能够在使用 mode='wrap'
参数调用的 imgaussfilt
called with the circular
padding option and scipy.ndimage.gaussian_filter
之间获得相对较好的匹配(优于 10e-10
百分比),前提是 imgaussfilt
使用默认过滤器2*ceil(2*sigma)+1
和 gaussian_filter
的大小指定 truncate=np.ceil(2*sigma)/sigma
。对于 circular
填充情况,这些设置会导致底层高斯核的半径和总体大小相同。我没有测试其他填充类型。
最近我致力于将 Matlab 代码转换为 python,并在 Internet 和文档中查找相同的函数,发现与 OpenCV 实现的结果完全相同。
% In Matlab
imgaussfilt(image, 100)
相当于
import cv2
# in python
cv2.GaussianBlur(image, ksize=(0, 0), sigmaX=100, borderType=cv2.BORDER_REPLICATE)
我试图在 Python 中复制 Matlab 的 imgaussfilter 行为,但我一直无法重现结果。文档没有太大帮助,因为没有解释到底做了什么(例如,该函数与 fspecial 有何不同,或者它与 Octave 的 imsmooth(以高斯作为参数)有何不同)。
Matlab代码
imgaussfilt(image,sigma)
有输出
[[-0.02936392 -0.03168419 -0.0343706 ... 0.03136455 0.02864487
0.02585145]
[-0.03212093 -0.0347433 -0.03775943 ... 0.03507484 0.03209807
0.02906134]
[-0.03512981 -0.03808864 -0.04147075 ... 0.03873834 0.03549163
0.03219311]
...
[-0.07713804 -0.08337475 -0.08975262 ... -0.04314206 -0.03945251
-0.03606256]
[-0.07145457 -0.07714807 -0.08297654 ... -0.03986635 -0.03641579
-0.03323718]
[-0.06605107 -0.07122191 -0.07651892 ... -0.03684535 -0.03362917
-0.03065128]]
我最接近 Python 的是:
Python
skimage.filters.gaussian(image, sigma=s,mode = 'nearest',truncate=2.0)
有输出
[[-0.02936397 -0.03168425 -0.03437067 ... 0.03136461 0.02864492
0.0258515 ]
[-0.03212099 -0.03474336 -0.03775951 ... 0.03507491 0.03209814
0.0290614 ]
[-0.03512988 -0.03808872 -0.04147083 ... 0.03873842 0.03549169
0.03219317]
...
[-0.07713819 -0.08337491 -0.08975279 ... -0.04314214 -0.03945259
-0.03606263]
[-0.07145471 -0.07714821 -0.0829767 ... -0.03986643 -0.03641586
-0.03323725]
[-0.06605119 -0.07122205 -0.07651907 ... -0.03684542 -0.03362923
-0.03065134]]
这是相似但不完全相同的结果。有没有更好地近似它的方法?我需要更改其中一个参数吗?
编辑: 如果您正在寻找使用 OpenCV 的近似值,@avisionx 在解决方案中提供了一个很好的起点。
这有多种可能的原因。由于 Matlab 不是开源软件,因此无法知道确切原因,但我们可以进行一些有根据的猜测。
关于什么 Gaussian filtering is doing: it replaces every pixel with a weighted sum of its neighbors. The weighting is determined by the Gaussian probability density function, 确切 权重由 sigma 决定,但也由 truncate
参数决定,您可以在 [=11] 中看到=] 文档。这个参数是必需的,因为从技术上讲,高斯函数永远不会衰减到零,它只是随着距离变得无穷大而接近零,所以 "perfect" 高斯模糊需要对无限数量的相邻像素求和,这是不可能的.因此,该函数需要决定距离零有多远才能停止求和。
另一个复杂因素是高斯模糊是 separable, which means that you can do a 2D (or nD) blur by blurring separately along each axis in sequence, which can reduce computing costs. Separability affects the order of computation, and floating point computation is not exact,因此如果 Matlab 和 Python 以不同的顺序执行操作,您会得到略有不同的结果。
即使您以完全相同的顺序过滤轴(您可以通过例如转置 Python 中的图像,过滤,然后将其转回),底层的低级数组计算库可能以不同的顺序对数组求和,这又会改变确切的结果。
简而言之,您所看到的差异的一些可能原因:
- 截断不同
- 不同的实现(是否分离过滤器)
- 轴的不同处理顺序
- 低级和的不同排序
可能没有办法解决这些问题,最后我的建议反映了 Cris Luengo 的评论:您的结果可能不应该依赖于比六位有效数字更精确的值。 Matlab 和 Python 之间的精确匹配在这里将毫无意义,因为两者都不能保证相对于高斯滤波器的理论值的完美准确性。两者都是近似值,完全匹配仅意味着您在两者中产生相同的近似值误差。
我能够在使用 mode='wrap'
参数调用的 imgaussfilt
called with the circular
padding option and scipy.ndimage.gaussian_filter
之间获得相对较好的匹配(优于 10e-10
百分比),前提是 imgaussfilt
使用默认过滤器2*ceil(2*sigma)+1
和 gaussian_filter
的大小指定 truncate=np.ceil(2*sigma)/sigma
。对于 circular
填充情况,这些设置会导致底层高斯核的半径和总体大小相同。我没有测试其他填充类型。
最近我致力于将 Matlab 代码转换为 python,并在 Internet 和文档中查找相同的函数,发现与 OpenCV 实现的结果完全相同。
% In Matlab
imgaussfilt(image, 100)
相当于
import cv2
# in python
cv2.GaussianBlur(image, ksize=(0, 0), sigmaX=100, borderType=cv2.BORDER_REPLICATE)