# Eroding noisy borders of polygons in an image

I am new to image processing, and this is the task at hand.

I have a mask image of shape 500x500x1 that contains polygons.

These polygons (=vector data: common term in remote sensing and GIS) are labeled, and will be used as my target later on to classify crops. This vector data has been rasterized (another remote sensing and GIS term) and resulted in the 500x500x1 mask. As you can see the borders of all polygons are noisy (contains pixels of different colors==> different classes) although each polygon should correspond to one class (one color). I am guessing that something went wrong during the rasterization process; I tried to erode the borders using simple morphological operations:

kernel  = cv2.getStructuringElement(cv2.MORPH_RECT, (2, 2))
erosion = cv2.erode(lulc_mask, kernel, iterations = 3)


However, this resulted in reducing the area inside the polygons and not the border.

Each time I increase the size of the kernel I basically erode the data from within the polygon, but the border remains the same. Any idea on how to solve this?

• Can I please ask if this is meant to be two questions, or one? The first question regarding what is going on with the mask is straightofrward. Do you also ask how to apply a morphological operator to achieve a specific modification of the image? And if yes, what would you be trying to achieve? – A_A Jul 22 at 8:08
• Yes, that's true, I want to erode the noisy borders of each polygon – Rim Sleimi Jul 22 at 21:01
• Can I please ask if this was resolved? – A_A Sep 30 at 13:12
• No it hasn't been solved x( – Rim Sleimi Sep 30 at 23:09

I have a mask image of shape 500x500x1 that contains polygons.

. . .

These polygons [...] are labeled

These two statements are incompatible. Assuming that the third number is the color depth, then 1-bit implies a binary mask, but each class being assigned to a different level implies a color depth >1.

With a 1-bit mask, binary erosion is applied. Otherwise grayscale erosion is applied, which is why you see those "out of class" values at the borders of the mask.

The simplest way to deal with this is to apply the erosion at each class within the image iteratively. So, collect the unique values from the mask in unique_classes. Then, for every level in unique classes, threshold the mask image (this returns a binary mask) apply the erosion and then bring it back to the level it is supposed to be.

Alternatively, duplicate the mask into two images, hold one back to be the one that describes the classes and threshold the second one so that it becomes a binary mask. In this setting, you apply erosion once, to the second mask, but use the first mask to decide which class a given pixel is a member of.

Hope this helps.