我有一个图像,我应用高斯模糊来同时使用cv2.GaussianBlur
和skimage.gaussian_filter
库,但我得到了明显不同的结果。我很好奇为什么,以及如何使skimage
看起来更像cv2
。我知道skimage.gaussian_filter
是scipy.scipy.ndimage.filters.gaussian_filter
的包装器。为了清楚地说明问题,为什么两个函数不同,可以做些什么来使它们更相似?
这是我的测试图片:
以下是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
答案 0 :(得分:2)
对于GaussianBlur,你使用的是一个相当大的内核(size = 33),这会导致很多平滑。平滑将严重依赖于内核大小。使用您的参数,每个新的像素值都是"平均值"在33 * 33像素"窗口"。
可以在此处找到cv2.GaussianBlur的定义 http://docs.opencv.org/3.1.0/d4/d13/tutorial_py_filtering.html#gsc.tab=0
相比之下,skimage.filters.gaussian似乎适用于较小的内核。在滑雪,"尺寸"由sigma定义,与此处描述的内核大小相关:https://en.wikipedia.org/wiki/Gaussian_filter
定义可以在这里找到:http://scikit-image.org/docs/dev/api/skimage.filters.html#skimage.filters.gaussian
为了获得相应的结果,您必须为OpenCV使用较小的内核。
此外,对于这两个库,我强烈建议使用最新的库版本。
答案 1 :(得分:2)
如果有人对如何使skimage.gaussian_filter()与Matlab的等效imgaussfilt()(我找到这个问题的原因)匹配感到好奇,请将参数'truncate = 2'传递给skimage.gaussian_filter()。 skimage和Matlab都将内核大小计算为sigma的函数。 Matlab的默认值为2.Surfmage的默认值为4,默认情况下会导致内核显着增大。
答案 2 :(得分:0)
这两个相等:
gau_img = cv2.GaussianBlur(img, (5,5), 10.0) # 5*5 kernal, 2 on each side. 2 = 1/5 * 10 = 1/5 * sigma
gau_img = skimage.filters.gaussian(img, sigma=10, truncate=1/5)
整个高斯核仅由sigma定义。但是,您用来模糊图像的高斯内核的哪一部分是由truncate
(在skimage中)或ksize
(在opencv中)定义的。
答案 3 :(得分:0)
根据[Scipy0.15.1 API][1]
:
scipy.ndimage.filters(img, sigma=sigma, truncate = 4.0)
它使用truncate * sigma中的内核大小设置高斯滤波器。在这种理解下,以下两个函数在灰度图像上会给出相同的结果:
trunc_val = 3
sigma_val = 3
k_size = int(sigma_val * trunc_val)
gau_img1 = cv2.GaussianBlur(img, (k_size,k_size), sigma_val)
gau_img2 = gaussian_filter(img, sigma = sigma_val, truncate = trunc_val)
cv2.imshow("cv2 res", gau_img1)
cv2.imshow("scipy res", gau_img2)
cv2.waitKey(-1)