Image Processing Series Part 6: Morphological Operations

Filed Under: Python Advanced
Opencv Part6 Min

In this article, we’re talking about Morphological Operations in image processing.

A large part of Image Processing tends to fall under the manipulation of images, much like what morphological operations do.

These operations can range from eroding the image to sharpening the image for details.
Blurring and Image Distortion assists in helping us to find features in the image.

We normally apply morphological operations to binary or grayscale images, as this allows us to extract information from the shapes and structures inside the images.

Prerequisites for Morphological Operations

It’s a good idea to have gone through the previous articles on Image Processing before this one, as it would allow you to be up to date with the basics of Image Processing.

This article will not be covering the explanation of the Set up, as that has already been done in the previous ones.

Here are a few links to the Image Processing series which you can visit for reference.

Morphological Operations

Now, let’s go over the morphological operations that we can take up in image processing.

Setting up the environment

Let’s first set the original image to access, and perform a few input operations before the morphological operations.

Here’s the code in order to do so,

# importing argument parsers
import argparse

# importing the OpenCV module
import cv2

# initializing an argument parser object
ap = argparse.ArgumentParser()

# adding the argument, providing the user an option
# to input the path of the image
ap.add_argument("-i", "--image", required=True, help="Path to the image")

# parsing the argument
args = vars(ap.parse_args())

# reading the image location through args
# and reading the image using cv2.imread
image = cv2.imread(args["image"])

# conversion of the image to grayscale
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# displaying the original image
cv2.imshow("Original", image)

You should receive an image that looks something like this,

Image
Original Eye Image

1. Erosion Operation

Erosion is an operation that literally does what it says – it erodes the image present in the foreground and makes it smaller.

To perform erosion, we define a structuring element and then, have it move from the top-left corner of the image to the bottom-right corner.

Erosion is useful in removal of blobs or disconnecting two connected objects.

Here’s the code in order to work with erosion,

# utilization of erosion threefold times
for i in range(0, 3):
    eroded = cv2.erode(gray.copy(), None, iterations=i + 1)
    cv2.imshow("Eroded {} times".format(i + 1), eroded)
    cv2.waitKey(0)

# destruction of all the windows
cv2.destroyAllWindows()
cv2.imshow("Original", image)

Here are a few examples of the erosion output,

2. Dilation Operation

Dilation is quite the opposite of the erosion, where it will grows the foreground pixels rather than eating away at the pixels.

We can use the cv2.dilate() to apply dilations on images.

Here’s the code in order to work with erosion,

# utilization of dilation threefold times
for i in range(0, 3):
    dilated = cv2.dilate(gray.copy(), None, iterations=i + 1)
    cv2.imshow("Dilated {} times".format(i + 1), dilated)
    cv2.waitKey(0)

# destruction of all the windows
cv2.destroyAllWindows()
cv2.imshow("Original", image)

A few examples of the dilation operations are given below,

3. Opening Operation

The Opening operation is a combination of an erosion, followed by a dilation.

This allows for us to remove blobs from an image.

We can then dilate to regrow the size of the object to it’s original form.

Here’s the code for Opening in OpenCV,

# creation of three different kernels to use in morphology
kernelSizes = [(3, 3), (5, 5), (7, 7)]

# utilization of the morphological Opening operation
for kernelSize in kernelSizes:
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, kernelSize)
    opening = cv2.morphologyEx(gray, cv2.MORPH_OPEN, kernel)
    cv2.imshow("Opening: ({}, {})".format(kernelSize[0], kernelSize[1]), opening)
    cv2.waitKey(0)

# destruction of all the windows
cv2.destroyAllWindows()
cv2.imshow("Original", image)

Here’s the resulting Opening Operation Outputs for our Image,

4. Closing Operation

Closing is the opposite of Opening, where we first dilate and then perform an erosion operation on the image.

Here’s the code to perform a Closing operation in OpenCV,

# utilization of the morphological closing operation
for kernelSize in kernelSizes:
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, kernelSize)
    closing = cv2.morphologyEx(gray, cv2.MORPH_CLOSE, kernel)
    cv2.imshow("Closing: ({}, {})".format(kernelSize[0], kernelSize[1]), closing)
    cv2.waitKey(0)

# destruction of all the windows
cv2.destroyAllWindows()
cv2.imshow("Original", image)

Here’s the Closing Operation Outputs,

5. Morphological Gradient

A morphological gradient is a difference between the dilation and erosion of an image.

We use this operation to find the outline of an image.

Which we will be covering in the near future!

# utilization of the morphological gradient operation
for kernelSize in kernelSizes:
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, kernelSize)
    gradient = cv2.morphologyEx(gray, cv2.MORPH_GRADIENT, kernel)
    cv2.imshow("Gradient: ({}, {})".format(kernelSize[0], kernelSize[1]), gradient)
    cv2.waitKey(0)

Here are a few outputs of the Morphological Operations,

6. Top Hat & Black Hat

The Top Hat and Black Hat operations are ones which find the difference between Original images and the Opening and Closing operations respectively.

Top Hat operations are used to reveal bright regions of images on dark backgrounds.

Black Hat operations are those that are used to reveal the opposite of Top Hat Operations.

Here’s the code for both these operations,

# structuring the kernel to be used in cv2.morphologyEx()
rectKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (13, 5))

# performing a blackhat morphological operation
blackhat = cv2.morphologyEx(gray, cv2.MORPH_BLACKHAT, rectKernel)

# performing a tophat morphological operation
tophat = cv2.morphologyEx(gray, cv2.MORPH_TOPHAT, rectKernel)

# Displaying the three different images
cv2.imshow("Original", image)
cv2.imshow("BlackHat", blackhat)
cv2.imshow("TopHat", tophat)
cv2.waitKey(0)

Top Hat Operation Output,

Image 19
Top Hat

Black Hat Operation Output,

Image 18
Black Hat

Conclusion

Morphological Operations are the operations that are performed in images to alter them to determine specific features.

They are used a lot of the times to probe an image using the structuring element that we’ve designed and put in.

Hope you gained something out of this article!

Look forward to more articles on Image Processing!

References

Leave a Reply

Your email address will not be published. Required fields are marked *

close
Generic selectors
Exact matches only
Search in title
Search in content