Introduction to Morphological Operators#
In this tutorial you are gonna explore kornia.morphology, that’s Kornia’s module for differentiable Morphological Operators.
By the end, you will be able to use morphological operations as easy as:
new_image = morph.operation(original_image, structuring_element)
But first things first, let’s prepare the environment.
Download Kornia#
If you don’t have Kornia installed, you can download it using pip.
%%capture
!pip install git+https://github.com/kornia/kornia
Prepare the image#
With kornia.morphology
, you can apply morphological operators in 3 channel color images. Besides, all operators are differentiable. Let’s download and read an image.
%%capture
!wget 'https://image.shutterstock.com/image-photo/portrait-surprised-cat-scottish-straight-260nw-499196506.jpg' -O img.jpg
We can use can use OpenCV to load the image.
import cv2
img = cv2.imread("img.jpg") # Download Image
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # Define RGB
Structuring element#
We have the original image ready to go, now we need the second part in the operation, the structuring element (aka Kernel).
The kernel must be a 2-dim tensor with odd sides, i.e. 3x3.
import torch
import kornia as K
device = 'cpu' # 'cuda:0' for GPU
kernel = torch.tensor([[0, 1, 0],[1, 1, 1],[0, 1, 0]]).to(device)
# to torch.tensor
img_t = K.image_to_tensor(img, keepdim=False)
img_t = img_t.float() / 255.
/home/docs/checkouts/readthedocs.org/user_builds/kornia-tutorials/envs/latest/lib/python3.7/site-packages/tqdm/auto.py:22: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html
from .autonotebook import tqdm as notebook_tqdm
Making plots!#
In this tutorial we are gonna compare the images before and after transforming them.
It make sense to create a function to plot and see the changes!
import matplotlib.pyplot as plt
from matplotlib import rcParams
def plot_morph_image(tensor):
# kornia.tensor_to_image
image = K.tensor_to_image(tensor.squeeze(0)) # Tensor to image
# Plot before-after
rcParams['figure.figsize'] = 20 ,20
fig, ax = plt.subplots(1,2)
ax[0].axis('off')
ax[0].imshow(img)
ax[1].axis('off')
ax[1].imshow(image)
Morphology#
The main goal of kornia.morphology is that you could easily implement several morphological operator as follows:
new_image = morph.operation(original_image, structuring_element)
Let’s check them all!
Dilation#
from kornia import morphology as morph
dilated_image = morph.dilation(img_t, kernel) # Dilation
plot_morph_image(dilated_image) # Plot

Erosion#
eroded_image = morph.erosion(img_t, kernel) # Erosion
plot_morph_image(eroded_image) # Plot

Open#
opened_image = morph.opening(img_t, kernel) # Open
plot_morph_image(opened_image)

Close#
closed_image = morph.closing(img_t, kernel) # Close
plot_morph_image(closed_image) # Plot

Morphological Gradient#
graded_image = morph.gradient(img_t, kernel) # Morphological gradient
plot_morph_image(1. - graded_image)

Bottom Hat#
bottom_image = morph.bottom_hat(img_t, kernel) # Black Hat
plot_morph_image(1. - bottom_image)

Top Hat#
toph_image = morph.top_hat(img_t, kernel) # Top Hat
plot_morph_image(1. - toph_image)

Conclusion#
And that’s it!
Now you know how to use Kornia to apply differentiable morphological operations in your PyTorch pipeline.
Many thanks for using Kornia, and have fun!