Put on the filter and we’ll clean out the fillers: Spatial Filtering and Morphological Operations with Images in Python

Nico Aguila
5 min readDec 27, 2020

Detecting and cleaning objects of interest in images can be done in multiple ways. For this post, we’ll be discussing two types: Spatial Filters and Morphological Operations.

Spatial Filters

Filters are basically matrices that apply a specific value onto a pixel based on their neighbors. In order to apply these matrices, convolution is done.

Let’s take a look at this cute little ornament and set it as our object of interest for this post:

#import libraries
from skimage.io import imread, imshow
from skimage.color import rgb2gray
import numpy as np
plant = rgb2gray(imread('medium/plant.jpg'))
imshow(plant)
Such a cute little ornament

The appearance of the image can be changed by simply applying filters to all the pixels. Some filters applied are shown below:

from scipy.signal import convolve2d
import matplotlib.pyplot as plt
%matplotlib inline
# Sobel Operators
# Horizontal Sobel Filter
kernel1 = np.array([[1, 2, 1],
[0, 0, 0],
[-1, -2, -1]])
# Vertical Sobel Filter
kernel2 = np.array([[1, 0, -1],
[2, 0, -2],
[1, 0, -1]])
# Left Diagonal Filter
kernel3 = np.array([[1, -1, -1],
[-1, 1, -1],
[-1, -1, 1]])
# Right Diagonal Filter
kernel4 = np.array([[-1, -1, 1],
[-1, 1, -1],
[1, -1, -1]])
# Edge Detection
kernel5 = np.array([[-1, -1, -1],
[-1, 8, -1],
[-1, -1, -1]])
# Sharpen
kernel6 = np.array([[0, -1, 0],
[-1, 5, -1],
[0, -1, 0]])
# Box Blur
kernel7 = (1 / 9.0) * np.array([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]])
# Gaussian Blur
kernel8 = (1 / 16.0) * np.array([[1., 2., 1.],
[2., 4., 2.],
[1., 2., 1.]])
def run_all_filters(): """applies all defined filters to the image"""
kernels = [kernel1,kernel2,kernel3,kernel4,
kernel5,kernel6,kernel7,kernel8]

kernel_names = ['Horizontal Sobel', 'Vertical Sobel','Left Diagonal', ' Right Diagonal',
'Edge Detection', 'Sharpen', 'Box Blur', 'Gaussian Blur']

k_dict = dict(zip(kernel_names, kernels))

for k in k_dict:
conv_im1 = convolve2d(plant, k_dict[k], 'valid')
fig, ax = plt.subplots(1,3, gridspec_kw=dict(width_ratios=(8,1,20),
wspace=0.5))
fig.suptitle(f'{k}', fontsize = 15)

kern = ax[0].imshow(k_dict[k], cmap='gray')
fig.colorbar(kern, cax=ax[1])
ax[2].imshow(abs(conv_im1), cmap='gray')
ax[2].set_xticks([]);
ax[2].set_yticks([]);
run_all_filters()
Sobel Filters
Diagonal Filters
Edge Detection and Sharpening
Blurring

Morphological Operations

Aside from applying filters to the images, Morphological Operations also apply matrices to pixels. However, a “structuring element” is taken into account instead, where image elements are cleaned up based on the correctness or completeness of the object.

Here, an object will be transformed based on a reference structure. Two basic morphological operations (erosion and dilation) can demonstrate the effect of the process.

Erosion — Reducing the structural element based on the reference structure. Just like soil erosion, the main idea of this is that it “erodes” the boundaries of the object of interest.

Dilation — Expanding the structural element based on the reference structure, basically this is the opposite of erosion.

Original Image

Say cheese!
#import necessary elements to demonstrate morphological operations
from skimage.morphology import erosion, dilation, opening, closing
kernel = np.ones((5,5),np.uint8)
kernel_small = np.ones((3,3),np.uint8)
imshow(erosion(smiley, kernel_small))
Original image (left) and Eroded image (right)

From the erosion, you can see that the lines of the smiley have been thinned by the reference image, or the kernel_small that we have used. Now let’s see what happens when we use dilation instead

imshow(dilation(smiley, kernel))
Original image (left) and Dilated image (right)

Just as what we have mentioned earlier, dilation thickens the smiley based on the kernel used.

Advanced Morphological operations are also available, such as successive erosion dilation operations. These are called Opening and Closing.

Opening — Removing white spots from images, much like removing salt particles from pepper

Closing — Removing dark spots from images, much like removing pepper particles from salt

Let’s see those two operations in action! Here’s our reference images for Opening and Closing

For Opening (left) and for Closing (right)
imshow(opening(smiley_open, kernel_small))
Before (left) and after (right) opening
imshow(closing(smiley_close, kernel))
Before (left) and after (right) closing

And there you have it! More knowledge on image detection and cleanup

--

--