# 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.

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.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.
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

### 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!