Reputation: 871
In theory a 2D convolution can be split as: G(x,y)*I = G(x) * G(y)*I
But when I try this:
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)
Here we observe that result 3 and 4 are the same (note: opencv filter2D function computes the correlation which is equal to the convolution if the kernel is symmetrical, else you'd have to flip the kernel and anchor point), but the question is:
Why isn't result1 = result2 ? (i.e why is result2 wrong)
Upvotes: 1
Views: 1168
Reputation: 60780
The issue is that you convolve twice in the same direction, rather than convolving once along each image axis:
result2 = signal.convolve(signal.convolve(image, kernel, mode='same'), kernel.T, mode='same')
# ^^^^^^^^
This gives me an average absolute difference (per pixel) with result1
in the order of 1e-15
.
Upvotes: 2