Search code examples
pythonimage-processingscipyconvolution

Edge detection not working as expected


I was just playing around with convolution and kernels in SciPy and Python. I used the following kernel for edge detection since it was listed in this wikipedia article:

kernel

This is the image I used:
lion

The result I got was pretty disappointing:
result

The code I used for the convolution:

edge = np.array([[-1, -1, -1], [-1, 8, -1], [-1, -1, -1]])
results = sg.convolve(img, edge, mode='same')
results[results > 255] = 255
results[results < 0] = 0

...and the code I used to read the image:

img = np.array(Image.open('convolution_test/1.jpg'))
img = img[:, :, 0]

Why am I getting these bad results?

TIA.


Solution

  • I think the problem is that your image works with unsigned integers. As a result if you for instance subtract one from zero, you get 0-1 = 255 for an uint8, and thus you get white where the value actually should be black.

    You can however easily overcome this issue by using signed integers (preferably with more depth). For instance:

    from PIL import Image
    import numpy as np
    import scipy.signal as sg
    
    img = np.array(Image.open('convolution_test/1.jpg'))
    img = img[:, :, 0]
    img = img.astype(np.int16)
    
    edge = np.array([[-1, -1, -1], [-1, 8, -1], [-1, -1, -1]])
    results = sg.convolve(img, edge, mode='same')
    results[results > 255] = 255
    results[results < 0] = 0
    
    results = results.astype(np.uint8)
    

    For me this generates the following image: enter image description here