In the previous blog, we touched on the introduction of morphological operations. In this blog and the next blog, we will discuss two of the most fundamental morphological operations – Erosion and Dilation. All other morphological operations can be defined in terms of these two basic operations. So, let’s get started.
Erosion
As clear from the name, this operation erodes or remove the pixels from the object boundary. In this, we ask the simple question of whether the structuring element fits the object or not? (“Fits” here means that all the image pixels underlying the structuring element (SE) should have the same value as that of the corresponding SE) If the image pixel fits, it is assigned 1, otherwise eroded (assigned 0). Thus if we use a square SE (say of size 3×3), then all the object boundary pixels will be eroded away. Now, let’s understand this in terms of the set operation.
In general, the erosion of the binary image A by some SE B is defined as
That is the set of all values of z such that B translated by z, is the subset of A or is contained in A. In other words, you shift the SE over the image and set the positions, where the SE doesn’t share any common element with the background, to 1 and erode all the remaining positions.
Thus this results in a decrease in the object area. If some holes are present in the object, this operation tends to increase the hole area. For binary images, this can be simply applied by taking the minimum of the neighborhood defined by the SE. Now, let’s see how to do this using OpenCV-Python. OpenCV provides a builtin function for this as shown below.
1 |
cv2.erode(src, kernel[, anchor[, iterations[, borderType[, borderValue]]]]) |
Here, src is the input image with any number of channels( all will be processed independently) and the kernel is the structuring element whose origin is defined by the anchor (default (-1,-1)). You can create the SE using cv2.getStructuringElement() or simply using numpy. Iterations specify how many times to repeat the erosion process. It is sometimes useful to pad the image to account for the boundary pixels or if the image is of non-regular shape and this can be done using the “borderType” and “borderValue” arguments. Below is an example where we erode the image with the rectangular SE.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
import cv2 import numpy as np # load the image img = cv2.imread('kang.png', 0) # Following are the two methods by which we can construct # the structuring element # Method-1: using numpy kernel_1 = np.ones((3,3), dtype='uint8') # Method-2: using opencv getStructuringElement() function kernel_2 = cv2.getStructuringElement(cv2.MORPH_RECT,(3,3)) # Apply the erosion function erosion = cv2.erode(b, kernel_2, iterations = 1) |
Different structuring elements, whether in the terms of shape or size, will produce different results. Mostly people prefer disc-shaped structuring element. If the size of the SE exceeds the size of the object, then the entire object will be eroded away. Erosion can be useful in removing noise (subjected to some conditions), detecting the object boundaries (subtracting the eroded image from the original one), separating the connected components or structures of a certain shape or size, etc.
In the next blog, we will discuss another morphological operation known as Dilation in greater detail. Hope you enjoy reading.
If you have any doubt/suggestion please feel free to ask and I will do my best to help or improve myself. Good-bye until next time.