cv2.GaussianBlur和cv2.filter2D与高斯内核的结果不同?

时间:2019-05-01 21:22:12

标签: python opencv torch cv2

我正在尝试在Python中移植一些lua / torch代码,有一个序列对图像运行高斯模糊,如下所示:

local gauK = image.gaussian(math.ceil(3*sigma)*2+1, sigma)
inp = image.convolve(inp, gauK, 'same')

为了在我的方法中复制这一点,我一直在研究cv2.GaussianBlur()和cv2.filter2D并传入一个高斯内核。

方法1(cv2.GaussianBlur):

kernel_size = int(math.ceil(3 * sigma) * 2 + 1)  # same size as the lua code
blurred_image = cv2.GaussianBlur(img, ksize=(kernel_size, kernel_size), sigma)

方法2(cv2.filter2D)

kernel_size = int(math.ceil(3 * sigma) * 2 + 1)  # same size as the lua code
gaussian_kernel = cv2.getGaussianKernel(kernel_size, sigma)
blurred_image_2 = cv2.filter2D(img, -1, gaussian_kernel)

在方法1和方法2之间,我得到了不同的图像。看来方法1的图像比方法2的图像更模糊。是否有任何理由为什么我在这里可能会得到不同的结果?我试图找出哪一个将匹配lua代码。谢谢。

2 个答案:

答案 0 :(得分:1)

这很奇怪;出于实用性考虑,我建议您选择一个满意的东西并使用它。除此之外,我猜想如何处理多个参数的语义会导致这种不匹配。而且,opencv的用于从kernelsize推断sigma或反之亦然的等式似乎与您的不匹配。

来自GaussianBlur docs

  
      
  • ksize:高斯核大小。 ksize.width和ksize.height可以不同,但​​它们都必须为正数和奇数。或者,它们可以为零,   然后根据sigma计算得出。
  •   
  • sigmaX:X方向上的高斯核标准偏差。
  •   sigmaY:Y方向上的高斯核标准差;如果sigmaY为零,则将其设置为等于sigmaX,如果两个sigmas均为零,   它们分别从ksize.width和ksize.height计算(请参见   cv :: getGaussianKernel以获取详细信息); 完全控制结果   无论将来对所有这些语义的可能修改如何,   建议您指定所有ksize,sigmaX和sigmaY。   

还有getGaussianKernel docs

  
      
  • 如果它为非正值,则根据ksize计算为sigma = 0.3\*((ksize-1)\*0.5 - 1) + 0.8
  •   

全部强调我的。您的sigma是否为负?这可能会导致不匹配。

编辑:只是注意到您希望它与lua代码匹配。我的建议是保存结果,然后在photoshop或您喜欢的图像编辑器中比较它们。如果从参考中减去测试,您应该能够看到差异,并且随着尝试的临近,总体上差异也应该更少。除非如此,否则您可以尝试阅读源代码以找出定义上的差异,或者自己编写!

祝你好运!

答案 1 :(得分:0)

cv2.getGaussianKernel函数返回1D向量,使其成为2D高斯矩阵,可以将其与其转置相乘(@用于矩阵乘法)。您可以尝试以下代码:

gaussian_kernel = cv2.getGaussianKernel(kernel_size, sigma)
kernel_2D = gaussian_kernel @ gaussian_kernel.transpose()
blurred_image_2 = cv2.filter2D(img, -1, kernel_2D)