Leo103
Leo103

Reputation: 871

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

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

Answers (1)

Cris Luengo
Cris Luengo

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

Related Questions