Tag Archives: dilation

Opening and Closing

In the previous blogs, we discuss two fundamental morphological operations – Erosion and Dilation. Both have their own advantages and disadvantages. For instance, erosion is useful in removing salt noise and structures of a certain shape but at the same time, if holes or gaps are present in the object, this tends to amplify them. So, what we want is something that removes the structures or fills holes/gaps without affecting the remaining foreground parts.

One plausible solution is to combine erosion and dilation operation. So, for instance, let’s take the case of noise removal. Like we discussed that the erosion will remove the salt noise but at the same time will shrink the foreground region also. To counter this, we apply dilation operation using the same structuring element. Because noise is removed, so dilation will only work on the shrunk foreground area and revert it back to the original. This process of applying erosion followed by dilation is known as Opening and in this blog, we will discuss this method in detail.

So, why is the name Opening? Because this opens up the gap between the objects connected by thin protrusions that are of size less than that of the structuring element. Below is the image where the bridge is 2 pixels wide while the SE is 3 pixels wide.

Now, let’s formulate the opening operation in terms of a set operation. The opening of binary image A by the structuring element B is defined as the erosion of A by B, followed by the dilation of the result by B. This can be stated using any of the two expressions as shown below

The second one states that the opening is the union of all the translations of SE B that fits into A. There is an interesting property associated with the opening known as idempotence. This simply states that if an image has been opened once, performing the subsequent opening operation with the same SE will have no effect on that image. This is because after opening the new boundaries created are such that the SE always fits inside them. Now, let’s discuss another operation – closing that is a dual of opening operation.

Closing

This is the just the reverse of Opening i.e Dilation followed by Erosion. Because this closes the holes/gaps present in the object while keeping the initial object size the same. That’s why the name Closing. Now, let’s formulate this in terms of a set operation.

Actual implementation involves rotating the SE by 180 degrees before performing dilation and erosion. But since our SE is mostly symmetric, we usually don’t care. Similar to the opening, this operator is also idempotent. Unlike opening, this fuses narrow breaks or bridges between the objects. Generally, good for removing pepper noise but not salt noise.

Now, let’s discuss how to implement these using OpenCV-Python. For Opening, one way is to first apply erosion and then dilation using the builtin functions we discussed earlier. Similarly, for closing also. Fortunately, OpenCV provides another function that directly implements these operations as shown below.

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)). Don’t know why the iterations argument is given because the opening and closing are idempotent operators. You can create the SE using cv2.getStructuringElement() or simply using numpy. 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. The “op” argument specifies which type of morphological operation to apply. Following are the types available.

  • MORPH_OPEN – an opening operation
  • MORPH_CLOSE – a closing operation
  • MORPH_GRADIENT – a morphological gradient
  • MORPH_TOPHAT – “top hat”
  • MORPH_BLACKHAT – “black hat”

Below is an example where we open and close the image with the rectangular SE.

In the next blog, we will discuss other morphological operators like morphological gradient, top hat, etc. 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.

Morphological gradient and Top-hat operators

In this blog, we will discuss various morphological operators such as morphological gradient, white and black top-hat transform, etc. All these operators can be easily obtained by combining erosion and dilation operations. So, let’s discuss each of these methods in detail.

Morphological Gradient

This is the difference between the dilation and erosion of an image. Because dilation and erosion mostly affect the pixels that are close to the boundary between the foreground and background, their difference generally yields the boundary and thus this is used for edge detection and segmentation tasks. Now, let’s discuss how to implement this using OpenCV-Python.

One approach is to use OpenCV cv2.dilate() and cv2.erode() functions and then subtract these two. Another approach is to use OpenCV cv2.morphologyEx() function with cv2.MORPH_GRADIENT flag as discussed in the previous blog. Both of these approaches are shown below.

Top Hat Transform

This is mainly used to extract small details from the images. There are two types of top hat operators namely

  • White top-hat transform: This is the difference between the image and its opening.
  • Black top-hat transform: Difference between the closing and the input image.

As we already know that opening eliminates thin protrusions and salt noise, thus the white top hat transform will return these elements. Similarly, the black hat transform will return the pepper noise and gaps/holes that are filled. That’s why the name “White” and “Black”. Thus depending upon the structuring element used, these can be useful for feature extraction.

Now, let’s discuss how to implement this using OpenCV-Python. This can be implemented either manually for instance first finding the image opening and then subtracting it from the original image. The second approach is to pass the corresponding flag in the cv2.morphologyEx() function as shown below.

This can also be used for tackling non-uniform illumination in images and thus can be a useful pre-processing tool for image segmentation tasks. The main idea is that you select the structuring element large enough that it erodes all the object region. Then the only thing remaining will be the background or the shading pattern. Subtracting this background from the image (or top-hat transform, in other words) will produce an image that reduces the non-uniform illumination effect. Thus the image can now be reasonably segmented. Below is an example of the image corrupted by non-uniform illumination and the result of applying white top-hat transform on that image. The image is thresholded using Otsu’s method.

That’s all for this blog. 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.

Dilation

In the previous blog, we discussed erosion operation. In this blog, we will cover another morphological operation – Dilation which is the dual of erosion. Dual in the sense that dilating the object region is equivalent to eroding the background region and vice versa. So, let’s get started.

Dilation

As clear from the name, this operation dilates or expands the object region. This is just opposite of erosion. In this, we ask the simple question of whether the structuring element hits the object or not? (“hits” here means that at least one of the image pixels underlying the structuring element (SE) should have the same value as that of the corresponding SE). If it hits, that pixel is set to 1 else set to 0. This is all the concept behind the dilation operation. Now, let’s formulate this in terms of the set operation.

In general, the dilation of the binary image A by some SE B is defined as

That is the set of all values of z such that the intersection of B (translated by z and reflected about its origin) and A is non-empty. In other words, we place the SE over the image so that the origin of the SE coincides with the input pixel position and compare the underlying image pixels with the pixels of the corresponding SE. If the SE shares at least one common element with its underlying image pixels, then the central image pixel is set to 1 else 0.

Thus this increases the size of the object. If some holes or pepper noise is present in the object, this results in bridging the gaps or removing the noise similar to what we discussed in the low pass filtering. The extent of thickening is controlled by the shape and size of the SE.

For binary images, this can be simply done by taking the maximum 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.

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) i.e at the center of the SE). You can create the SE using cv2.getStructuringElement() or simply using numpy. Iterations specify how many times to repeat the dilation 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 dilate the image with the rectangular SE.

Similar to erosion, this can also be used to remove noise, detect the object boundary, etc. Although neither erosion nor dilation alone is effective in reducing noise. A more efficient approach is erosion followed by dilation or opening operation in general. Most of the morphological algorithms which we will discuss in the next blogs are also based on dilation and erosion. 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.