Home > other >  How to separate monochromatic objects of different sizes in opencv
How to separate monochromatic objects of different sizes in opencv

Time:09-30

I want to separate a noiseless 1-bit (black and white) image with white circles based on the concave part of the outline. Please refer to the picture below.

This is the white object to separate:

white circle

The target result is:

goal circle

Here is my implementation with the watershed algorithm:

implemented circle

The above result is not what I want. If the size of the separated objects is similar, my algorithm is fine, but if the size difference is large, a problem occurs as shown in the picture above. I would like to implement an opencv algorithm that can segment a region like the second picture.

However, the input photo is not necessarily a perfect circle. It can be oval like the picture below:

white ellipse

Or it can be squished:

squished shape squished shape color

However, I would like to separate it based on the concave part of the outline anyway.

I think it can be implemented by using the distanceTransform function well, but I'm not sure how to approach it. Please let me know which way to refer. Thank you.

CodePudding user response:

Here is an algorithm which should give you a good start.

  1. Compute all contours.
  2. For each contour compute the convexity defects. If there is no defect the contour is an isolated circle and you can segment it out.
  3. After you handled all the isolated circles, you can work out the remaining contours by counting the convexity defects: the number of circles N for each contour is the number of convexity defects divided by 2.
  4. Use a clustering algorithm (https://scikit-learn.org/stable/modules/generated/sklearn.mixture.GaussianMixture.html should do well given the shapes you have) and cluster the "white" points using N as the number of clusters to be found.

CodePudding user response:

If you want to find the minimal openings, you can use a medial axis based approach.

Pseudo code:

compute contours of bitmap
compute medial-axis of bitmap 

for each point on medial-axis:
  get minimal distance d from medial axis algorithm
  for each local minimum of distance d:
    get two points on bitmap contours with minimal distance that are at least d apart from each other
    use these points for deviding line  

If you need a working implementation in python, please let me know. I would use skimage lib. For other languages you might have to implement medial-axis on your own. But that shouldn't be a big deal.

  • Related