Gus B
Gus B

Reputation: 297

Skimage merge over-segmented regions

I am trying to split this image into nine separate regions (the overlapping circlular areas). Since the circles overlap, I thought watershed segmentation would be the best method for this. I followed this scikit-image.org example to perform the technique on my image, and the image is over-segmented and I get 10 segments instead of nine, as checked with the ndi.labels function.

Increasing the size of the footprint within the peak_local_max function raises the problem of under-segmenting, so I think it is better to over-segment and then combine the regions that should be a single region. You can see in the provided output that the eighth circle is split into two separate regions. I used the regionprops function to draw the bounding boxes.

segmented_image_example.png

import matplotlib.pyplot as plt
from scipy import ndimage as ndi

from skimage import io, img_as_uint
from skimage.filters import median, threshold_minimum
from skimage.morphology import disk, square, closing, watershed
from skimage.feature import peak_local_max


image_bw = ('example_binary.tif')

distance = ndi.distance_transform_edt(image_bw)
local_maxi_disk10 = peak_local_max(distance, indices=False, 
                                   footprint=np.ones((400, 400)), 
                                   labels=image_bw)

markers, num_features = ndi.label(local_maxi_disk10)
labels = watershed(-distance, markers, mask=image_bw)
print('Number of features (ndi.label):', num_features)

fig, axes = plt.subplots(1, 3, figsize=(10, 4), sharex=True, sharey=True)
ax = axes.ravel()

ax[0].imshow(image_bw)
ax[0].set_title('Image Binary')
ax[1].imshow(-distance)
ax[1].set_title('Distances')
ax[2].imshow(labels)
ax[2].set_title('Separated objects')

for a in ax:
    a.set_axis_off()

plt.tight_layout()
plt.show()

The final goal is to take the parts of the image that belong to each individual circle and save them as their own images, so to combine the regions that are incomplete, I could just add together their bounding boxes. However, it seems like there should be a way to combine multiple regions from regionprops or perhaps even different labels from the watershed process itself. Can anybody help send me in the right direction to figure out how to do this by merging regions/labels? I will also attach the binary image I used.

example_binary.tif

Upvotes: 3

Views: 2652

Answers (1)

Juan
Juan

Reputation: 5738

You can probably use a Region Adjacency Graph (RAG), and then merge the nodes according to some criterion [1] [2] [3]. Finding the right criterion is often hard, though.

If you want to do it by hand, you can do it with NumPy indexing:

import numpy as np

def merge_labels(labels_image,
                 labels_to_merge,
                 label_after_merge):
    labels_map = np.arange(np.max(labels_image) + 1)
    labels_map[labels_to_merge] = label_after_merge
    return labels_map[labels_image]

Upvotes: 3

Related Questions