I have a segmented image as shown below
There is a very thin line of different colors on the edges of the vehicle (Red patch where the person is driving). I would like to get rid of this thin line by assigning different label ids (either red or black) based on the neighboring pixels. I know how to extract pixels based on the required color or even ids. But in this case, the color or ID is not fixed, it could be different colors or IDs in a different image. I am not able to come up with a way to extract just these pixels. Can someone help me with extracting pixels that belong to the thin line?
8
Here’s what I was alluding to in the comments. Select the black pixels, dilate them a little, then merge them back into original image:
#!/usr/bin/env python3
import cv2 as cv
import numpy as np
# Load image
im = cv.imread('scene.png', cv.IMREAD_COLOR)
# Select black pixels
blacks = ( np.all(im == (0, 0, 0), axis=-1) * 255 ).astype(np.uint8)
cv.imwrite('DEBUG-blacks-before.png', blacks)
# Dilate blacks with a circular structuring element
SE = cv.getStructuringElement(cv.MORPH_ELLIPSE, (4,4))
blacks = cv.morphologyEx(blacks, cv.MORPH_DILATE, SE)
cv.imwrite('DEBUG-blacks-after.png', blacks)
# Select darker pixel at each location - the tilde (~) means the inverted image
res = np.minimum(im, ~blacks[..., np.newaxis])
cv.imwrite('result.png', res)
Here is an animation, alternating between the two debug images, showing how the dilation affects the blacks:
Notes:
-
Now you can see how dilation works, you can adapt it to Christoph’s other suggestions.
-
The
np.newaxis
thing makes a [M,N] single colour channel array compatible with an [M,N,3] 3-colour channel array. -
Make the structuring element larger to fatten the black lines even more, e.g.
cv.getStructuringElement(cv.MORPH_ELLIPSE, (5,5))
4