我使用cv2.GaussianBlur
和skimage.gaussian_filter
库对一张图像应用高斯模糊,但得到的结果却截然不同。我很好奇为什么,以及如何才能使skimage
看起来更像cv2
。我知道skimage.gaussian_filter
是scipy.scipy.ndimage.filters.gaussian_filter
的 Package 器。为了清楚地说明这个问题,为什么这两种功能不同?2怎样做才能使它们更相似?
下面是我的测试图像:
下面是cv2
版本(看起来比较模糊):
以下是skimage
/scipy
版本(看起来更清晰):
详细信息:skimage_response = skimage.filters.gaussian_filter(im, 2, multichannel=True, mode='reflect')
cv2_response = cv2.GaussianBlur(im, (33, 33), 2)
个
因此sigma=2,滤波器的大小足够大,不会产生差异,Imagemagick covnert -gaussian-blur 0x2
在视觉上与cv2
一致。
版本:cv2
=2.4.10,skimage
=0.11.3,scipy
=0.13.3
5条答案
按热度按时间u3r8eeie1#
如果有人想知道如何使skimage.gaussian_filter()与Matlab的imgaussfilt()相匹配(这也是我提出这个问题的原因),请将参数'truncate=2'传递给skimage.gaussian_filter()。skimage和Matlab都将内核大小作为sigma的函数来计算。Matlab的默认值是2。Skimage的默认值是4,默认情况下会产生一个明显更大的内核。
wr98u20j2#
对于GaussianBlur,您使用了一个相当大的内核(大小=33),这会导致大量的平滑。平滑将在很大程度上取决于您的内核大小。使用您的参数,每个新的像素值将在一个33*33像素的“窗口”中“平均”。
有关cv2.GaussianBlur的定义,请访问http://docs.opencv.org/3.1.0/d4/d13/tutorial_py_filtering.html#gsc.tab=0
相比之下,skimage.filters.gaussian似乎可以在更小的内核上工作。在skimage中,“大小”由sigma定义,sigma与内核大小相关,如下所述:https://en.wikipedia.org/wiki/Gaussian_filter
定义可在此处找到:http://scikit-image.org/docs/dev/api/skimage.filters.html#skimage.filters.gaussian
为了获得相应的结果,您必须使用较小的OpenCV内核。
此外,对于这两个库,我强烈建议使用最新的库版本。
zpgglvta3#
这两者是相等的:
整个高斯核只由sigma定义,但是你用高斯核的哪一部分来模糊图像是由
truncate
(在skimage中)还是ksize
(在opencv中)定义。but5z9lq4#
根据
[Scipy0.15.1 API][1]
:它将高斯滤波器的核大小设置为truncate * sigma。在这种理解下,下面两个函数将在灰度图像上给予相同的结果:
部分测试结果:截断瓦尔= 3;西格玛瓦尔= 3 x1c 0d1x
截断瓦尔= 3;西格玛瓦尔= 1
截断瓦尔= 3;西格玛值= 9
qaxu7uf25#
opencv
和scipy
都允许指定sigma
,它在两个库中具有相同的含义。内核大小的确定方式不同:scipy
中,它是从truncate
参数派生的,即int(truncate * sigma + 0.5)
opencv
中,它可以独立于sigma
指定(如果省略,它的计算方式与sigma = 0.3*((ksize-1)*0.5 - 1) + 0.8
不同。因此,要获得相同的结果,您需要显式指定内核大小和sigma:
其余差异(参见第4个图)是由浮点计算和不同的结果数据类型(
uint8
与float64
)引起的。