我正在尝试在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代码。谢谢。
答案 0 :(得分:1)
这很奇怪;出于实用性考虑,我建议您选择一个满意的东西并使用它。除此之外,我猜想如何处理多个参数的语义会导致这种不匹配。而且,opencv的用于从kernelsize推断sigma或反之亦然的等式似乎与您的不匹配。
- ksize:高斯核大小。 ksize.width和ksize.height可以不同,但它们都必须为正数和奇数。或者,它们可以为零, 然后根据sigma计算得出。
- sigmaX:X方向上的高斯核标准偏差。
sigmaY:Y方向上的高斯核标准差;如果sigmaY为零,则将其设置为等于sigmaX,如果两个sigmas均为零, 它们分别从ksize.width和ksize.height计算(请参见 cv :: getGaussianKernel以获取详细信息); 完全控制结果 无论将来对所有这些语义的可能修改如何, 建议您指定所有ksize,sigmaX和sigmaY。
- 如果它为非正值,则根据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)