Search code examples
pythonnumpysobel

Applying Sobel operator in numpy to simple binary image


I'm trying to apply the Sobel operator to a simple binary image, but the resulting gradient is flipped (when comparing to the output of scipy's signal.convolve2d function.

from scipy import signal
import numpy as np
import matplotlib.pyplot as plt


def sobelx_homemade(arr, kx):
    offset = 1
    sx = np.zeros(arr.shape)
    for y in range(offset, arr.shape[0] - offset):
        for x in range(offset, arr.shape[1] - offset):
            rstart, rend = y-offset, y+offset+1
            cstart, cend = x-offset, x+offset+1
            w = arr[rstart:rend, cstart:cend]
            Ix = kx * w
            sx[y, x] = Ix.sum()
    return sx

A = np.array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                   [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                   [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                   [0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0],
                   [0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0],
                   [0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0],
                   [0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0],
                   [0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0],
                   [0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0],
                   [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                   [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                   [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])


kx = np.array([
    [-1, 0, 1],
    [-2, 0, 2],
    [-1, 0, 1]
], dtype=np.float)

ky = np.array([
    [1, 2, 1], 
    [0, 0, 0], 
    [-1, -2, -1]
], dtype = np.float)

Gx = signal.convolve2d(A, kx, boundary='symm', mode='same')
Gy = signal.convolve2d(A, ky, boundary='symm', mode='same')

# calculate homemade sobel x gradient
myGx = sobelx_homemade(A, kx)

plt.subplot(131)
plt.title("Original")
plt.imshow(A, cmap="gray")
plt.subplot(132)
plt.title("Gx")
plt.imshow(Gx, cmap="gray")
plt.subplot(133)
plt.title("My Gx")
plt.imshow(myGx, cmap="gray")

output of script, gx and my gx should match

I expect the images labeled "Gx" and "My Gx" to be identical.


Solution

  • So, it turns out that a true convolution flips the kernel/filter matrix, which explains the flipped result.

    This video from Andrew Ng, explains the differences between textbook convolution and cross-correlation commonly used in machine learning style image processing: https://youtu.be/tQYZaDn_kSg?t=308