Delineate contributing Area of polygon with Watershed OpenCV, ConnectedComponent does not label all objects in image

Viewed 30

I am trying to delineate the contributing area of each shape in an image by using the distance and watershed function in OpenCV. This is the image: enter image description here This is what I have been doing:

img=cv2.imread('Wetlands.png')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray,128,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
dist = ndi.distance_transform_edt(thresh)
dist_visual = dist.copy()
dist_png.save(path.split('.')[0]+'_dis.png')
dis=cv2.imread('Wetlands_dis.png')
# Marker labelling
ret, markers = cv.connectedComponents(gray)

I want to show the area around each shape or polygon by based on the distance value around each component so:

wetland = cv.watershed(dis,markers)

The final result is what exactly I am looking for but the main problem is that the marker does not include all the components in the gray image with one value ( it is ignoring all the big and channel shape polygons in the image). This is the final result: This is

and I showed by a red line how the connectedComponent is ignoring those channel shape objects. Any idea about this?

Method2:

I also tried this :

image=cv2.imread('/content/drive/MyDrive/try/test_function/covert/Wetlands.png')
original= image.copy()
gray=cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur=cv2.GaussianBlur(gray, (5,5), 0)
thresh=cv2.threshold(blur, 128, 255, cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)[1]
thresh2=cv2.threshold(blur, 128, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)[1]
kernel=cv2.getStructuringElement(cv2.MORPH_CROSS, (3, 3))
dilate = cv2.dilate(thresh, kernel, iterations=1)
dilate2 = cv2.dilate(thresh2, kernel, iterations=1)
opening = cv2.morphologyEx(dilate, cv2.MORPH_OPEN, kernel)
opening2 = cv2.morphologyEx(dilate2, cv2.MORPH_OPEN, kernel)
dist = ndi.distance_transform_edt(opening)
dist2 = ndi.distance_transform_edt(opening2)
dist_visual = dist.copy()
dist_png=Image.fromarray(np.uint8(dist_visual))
dist_png.save(path.split('.')[0]+'_dis.png')
# sure background area
sure_bg = opening2
ret, sure_fg = cv.threshold(dist2,0.7*dist2.mean(),255,0)
# Finding unknown region
sure_fg = np.uint8(sure_fg)
unknown = cv2.subtract(sure_bg, sure_fg)

# Marker labelling
ret, markers = cv2.connectedComponents(sure_fg)

# Add one to all labels so that sure background is not 0, but 1
markers = markers+1

markers[unknown == 255] = 0
dis=cv2.imread('/content/drive/MyDrive/try/test_function/covert/Wetlands_dis.png')
wetland = cv.watershed(dis,markers)

this time the connectedComponent labels more components but still missing large shapes.

This is the new image: enter image description here

I appreciate any feedback.

0 Answers
Related