理论上,二维卷积可以拆分为: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错误)
答案 0 :(得分:2)
问题是,您在同一方向上进行了两次卷积,而不是沿着每个图像轴进行一次卷积:
result2 = signal.convolve(signal.convolve(image, kernel, mode='same'), kernel.T, mode='same')
# ^^^^^^^^
这给了我result1
的平均绝对差(每个像素),顺序为1e-15
。