David Harar
David Harar

Reputation: 310

Using convolution in order to derive an image rise wrong results on the edges

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.

Upvotes: 0

Views: 338

Answers (1)

David
David

Reputation: 8298

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

Upvotes: 1

Related Questions