卷积:2d vs 1d 2-pass 给出不同的结果

convolution: 2d vs 1d 2-pass giving different results

理论上二维卷积可以拆分为:G(x,y)*I = G(x) * G(y)*I

但是当我尝试这个时:

import cv2
import scipy.signal as signal
import numpy as np

image = np.random.randint(255, size=(5, 5))
kernel = cv2.getGaussianKernel(13, 2)
kernel_2D = np.outer(kernel, kernel)

result1 = signal.convolve(image, kernel_2D, mode='same')
result2 = signal.convolve(signal.convolve(image, kernel, mode='same'), kernel, mode='same')

result3 = cv2.filter2D(image,-1, kernel_2D, borderType=0)
result4 = cv2.sepFilter2D(image*1.0, -1, kernel, kernel, borderType=0)

这里我们观察到结果 3 和 4 是相同的(注意:opencv filter2D 函数计算的相关性等于卷积如果内核是对称的,否则你必须翻转内核和锚点) , 但问题是:

为什么不是 result1 = result2 ? (即为什么 result2 错误)

问题在于您在同一方向上进行了两次卷积,而不是沿每个图像轴进行一次卷积:

result2 = signal.convolve(signal.convolve(image, kernel, mode='same'), kernel.T, mode='same')
#                                                                      ^^^^^^^^

这让我得到了 result1 的平均绝对差值(每像素),顺序为 1e-15