Introduction
This tutorial is about yet another morphological operation – erosion. In the previous tutorial we saw its counterpart – dilation. If you remember, dilation was enlarging the boundaries of the foreground regions in an image. Erosion is quite the opposite – it shrinks the boundaries of those regions.
Again I will have a short introduction to the process, without going into any mathematical details. Then I will introduce some source code, which applies erosion on a given image. The tutorial and the source code might seem similar to the tutorial for the dilation, but this is because both process go hand by hand and they have a lot in common.
The erosion process overview
The erosion is a morphological operation which shrinks the boundaries of regions of foreground pixels – typically the white pixels. In case of a binary images, the erosion will shrink all the white regions, while enlarging the black ones. This will cause the removal of any small white dots from the image and will enlarge any black holes inside the white objects.
The erosion process also uses a structuring elements. It is applied on the input image and based on its size the effect of the erosion could be stronger or weaker. There are several types of structuring elements, that we could use. The most common one is a rectangle or in most cases a square. But OpenCV also supports a cross and an ellipse. It’s really up to you to find the perfect structuring element. You will need to play with its sizes and type until you get the desired result.
Demonstration on how the erosion works
Input image
Structuring element
Result
Here we have one input image with several white pixels and one cross structuring element. The erosion works in kinda the following way (you can think of it this way). It finds one white pixel in the input image, then on top of that white pixel it pastes the cross element. The center of the cross is on top of the white pixel.
What will happen next is that it checks whether the structuring element covers only white pixels. If the cross covers only white pixels, then the current center pixel will remain white. If any of the pixels, covered by the structuring element is black, then the center pixel is turned black. This will go for each white pixel in the input image. In our case when we put the cross on the second row second cell it will cover only white pixels. That is why we leave the second row, second cell white. Same goes for the third row and third cell.
Here is very important to understand that the new black pixels are applied to the result image and not on the input image. This way the input image will remain the same and we will go over all the original white pixels, this including the pixels which it might have removed previously. Look at the above example and try to perform the operations by yourself.
I hope the example is understandable. In case you have troubles, write a comment in the comments section.
This was some simple overview about the erosion process. More information you can find here and here.
The source code for the erosion operation
Next, let’s see some source code. OpenCV already has a function to perform the erosion . That is why the source code is simple.
using namespace cv; void erodeImage() { // Path to the input image std::string l_pathToInputImage{ "../Resources/hazard.jpg" }; // Create an object to hold the image data of the first image Mat l_image; // Read the image date from a file with no change to color scheme l_image = imread(l_pathToInputImage, IMREAD_UNCHANGED); // Check if we have read the first image data correctly if (!l_image.data) { std::cout << "No image data \n"; return; } // Create the output image matrix Mat l_outputImage = l_image.clone(); // Creating the structuring element for the morphological operation int l_erosionSize = 3; Mat l_erodingElement = getStructuringElement( MORPH_RECT, Size( 2*l_erosionSize + 1, 2*l_erosionSize+1 ), Point( l_erosionSize, l_erosionSize ) ); // Eroding the image erode( l_image, l_outputImage, l_erodingElement ); // Display the input image namedWindow("Input", WINDOW_NORMAL); cv::imshow("Input", l_image); // Display the result image namedWindow("Result", WINDOW_NORMAL); cv::imshow("Result", l_outputImage); }
Firstly, we read the input image and check if we have read the image data correctly. Then we create a clone of the input image data, which will hold the result of the erosion. Next thing we do is to create the structuring element. Luckily in OpenCV there is the getStructuringElement() function which does this for us. The function takes the shape of the element we want to create as a first argument. Here is more information about the available shapes. In our case I am choosing a rectangle. Next, I am setting the size of the structuring element. The third argument is the anchor or what will be considered as a center of the structuring element.
After we have the structuring element it is time to call the function to erode the image. The OpenCV function erode() is responsible for applying the erosion over the input image. As you can see from the documentation it takes as a first argument the input image. Following is the output image and then we provide the structuring element. There are four more arguments which we use with their default values, because they work for us as they are.
The result of the erosion operation
Finally we display the input image and the result of the erosion operation. One thing that is worth mentioning is that OpenCV treats the black color of the binary image as a background and the white color as a foreground. That is why if you have seen in some books or articles about the erosion, they sometimes use the black color as a foreground so eroding a binary image might show the black color shrinking. In the case of OpenCV the white color is the foreground. So when eroding an image in OpenCV the white color is shrinking.
Here is my result with one binary image:

What you can see here is that the thinner white regions are almost gone and the black holes are bigger.
Here is another eroded image. You can see how thinner the result symbol is.

Finally, the result of eroding a grayscale image. As you can see the white pixels has shrunk, the black pixels has grown and the image is somehow blurred.

Conclusion
In this tutorial we saw how to apply the erosion operation on an image using a ready OpenCV function. We had a brief overview on what is erosion and how can we use it. The source code we have so far is available for download below and also on GitHub.
Next we will get familiar with another morphological operations.

Passionate developer, loving husband and caring father. As an introvert programming is my life. I work as a senior software engineer in a big international company. My hobbies include playing computer games (mostly World of Warcraft), watching TV series and hiking.