6.0 Morphological Image Processing
Morphological operations are a set of non-linear techniques that process images based on their shapes. They are typically applied to binary or grayscale images and use a small template, called a “structural element” or kernel, to probe the image. The kernel is moved across the image, and its shape determines how the underlying image structure is modified. This module will cover the two fundamental morphological operations, Dilation and Erosion, as well as more complex transformations built upon them.
6.1 Core Concepts: Dilation and Erosion
Dilation and Erosion are the foundational operations in morphological image processing. They are aimed at removing noise and settling imperfections to clarify the image.
Dilation
Dilation is an operation that “grows” or “thickens” the bright regions in an image. It works by convolving the image with a kernel. For each position of the kernel on the image, the value of the corresponding output pixel is set to the maximum pixel value within the kernel’s neighborhood. This causes the boundaries of bright foreground objects to expand.
To perform this expansion, we use the dilate() function from the Imgproc class. The kernel is typically created using getStructuringElement().
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.Size;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
public class DilateTest {
public static void main( String[] args ) {
System.loadLibrary( Core.NATIVE_LIBRARY_NAME );
Mat src = Imgcodecs.imread(“path/to/your/image.jpg”);
Mat dst = new Mat();
Mat kernel = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(5, 5));
Imgproc.dilate(src, dst, kernel);
Imgcodecs.imwrite(“path/to/your/dilated_image.jpg”, dst);
System.out.println(“Image Processed with Dilation.”);
}
}
In the output image, the bright areas will appear larger and more connected than in the original.
Erosion
Erosion is the opposite of dilation. It “shrinks” or “thins” bright regions. It computes the minimum pixel value over the area of the kernel and replaces the output pixel with that minimum value. This causes the boundaries of bright objects to contract and dark regions (holes) within them to grow. It is useful for removing small noise specks.
To achieve this shrinking effect, we use the erode() function, which acts as the inverse of dilation, using the same type of kernel.
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.Size;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
public class ErodeTest {
public static void main( String[] args ) {
System.loadLibrary( Core.NATIVE_LIBRARY_NAME );
Mat src = Imgcodecs.imread(“path/to/your/image.jpg”);
Mat dst = new Mat();
Mat kernel = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(5, 5));
Imgproc.erode(src, dst, kernel);
Imgcodecs.imwrite(“path/to/your/eroded_image.jpg”, dst);
System.out.println(“Image processed with Erosion.”);
}
}
Compared to the dilation example, the output image here will show smaller and thinner bright regions.
6.2 Advanced Morphological Operations
OpenCV combines dilation and erosion to create more complex and powerful morphological transformations. These are accessible through the versatile morphologyEx() function. Its key parameters are src, dst, op (the operation type), and kernel.
The table below lists the available operations specified by the Imgproc.MORPH_* constants.
| Operation | Description |
| MORPH_OPEN | An erosion followed by a dilation. Useful for removing small noise. |
| MORPH_CLOSE | A dilation followed by an erosion. Useful for closing small holes. |
| MORPH_GRADIENT | The difference between the dilation and erosion of an image. |
| MORPH_TOPHAT | The difference between the input image and its opening. |
| MORPH_BLACKHAT | The difference between the closing of the input image and the image itself. |
Let’s use the Top Hat operation as a case study. This transform is useful for revealing small details and bright elements on a dark background.
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
public class MorphologyExTest {
public static void main(String args[]) {
System.loadLibrary( Core.NATIVE_LIBRARY_NAME );
Mat src = Imgcodecs.imread(“path/to/your/image.jpg”);
Mat dst = new Mat();
Mat kernel = Mat.ones(5, 5, CvType.CV_32F);
Imgproc.morphologyEx(src, dst, Imgproc.MORPH_TOPHAT, kernel);
Imgcodecs.imwrite(“path/to/your/morph_tophat_image.jpg”, dst);
System.out.println(“Image Processed with MORPH_TOPHAT.”);
}
}
The output of the “top hat” transform will be an image that highlights the bright features that are smaller than the structuring element.
Having explored shape-based processing, we will now move to techniques focused on identifying significant structural features like edges and lines within an image.