0

I'm taking an online course of image processing in which all the problem sets were given in MATLAB. Nevertheless, I'm trying to solve them with Python and I get some unexpected results when I try to compute image derivative using convolution with the following kernel: [0.5,0, -0.5].

Given row i, I want to calculate the columns derivatives using convolution with g.

image[i,:] = [1,2,3,4]
g = [0.5,0,-0.5]

I convolute the two using the following code:

    inImage_i_conv = np.zeros_like(inImage_i)

    for j in range(0,len(inImage_i)-1):
        conv = []
        for m in range(len(dy)):
            l = m-1
            conv.append(inImage_i[j-l]*dy[l+1])
        inImage_i_conv[j] = np.sum(conv)

and the result is array([-1, 1, 1, 0]). The reason for having -1 at the beginning is that under j = 0 and l = 1, I actually get the [-1] element, which in Python is the nth element.

Should I add a 0 before the ith row (or equivalently 0 column on the leftmost column of the image)? Should I add a copy of the first element to the left?

What is the common practice? because my results are obviously wrong.

David
  • 8,113
  • 2
  • 17
  • 36
David Harar
  • 301
  • 2
  • 12
  • 1
    You don't want to use built in functions? – David Oct 04 '20 at 07:57
  • Well, I'm not doing this in order to get credits but in the PS file it was written to "Write a function that computes the magnitude of an image derivative. You should derive the image in each direction separately (rows and column) using simple convolution with [1; 0; −1] and [1, 0, −1] to get the two image derivatives. Next, use these derivative images to compute the magnitude image." So I'll keep trying to manually compute them and if I would not succeed I'll go to the built in options. – David Harar Oct 04 '20 at 08:05

1 Answers1

1

So if you wish to right the convolution by yourself here is a good start.

import numpy as np

def zero_pad(X, pad):
    X_pad = np.pad(X, pad, 'constant', constant_values=0)
    return X_pad

def conv_step(x, W):
        return np.sum(np.multiply(x, W))

def conv(s, k):
    diff = abs(len(s) - len(k) - 1)
    slide = len(k)
    # flip kernel
    k = k [::-1]
    Z = np.zeros(shape=len(s)-diff)
    for i in range(Z.shape[0]):
        Z[i] = conv_step(s[i:i+slide], k)
    return Z

s = [1,2,3,4]
g = [0.5,0,-0.5]
print(np.convolve(s, g, 'same'))  # [ 1.   1.   1.  -1.5]
print(conv(zero_pad(s,1),g))  # [ 1.   1.   1.  -1.5]

You can see that it returns the same as the built-in function np.convolve. It follows the basic steps in convolution, which you see in https://en.wikipedia.org/wiki/Convolution

  1. pad the vector to the desired length
  2. flip the kernel (or the input)
  3. create a fill-to vector of the desired length
  4. iterate over it and each time do the multiplication followed summation
David
  • 8,113
  • 2
  • 17
  • 36