Consider the following image

enter image description here

I would like to cluster the points obtained after edge detection and subsequently, would like to color the clustered edge points.

My attempt:

img = URLExecute["https://i.sstatic.net/4q309.png"];
edgeImg = img // EdgeDetect;
edgePoints = PixelValuePositions[edgeImg, 1];
clusteredEdgePoints = FindClusters[edgePoints, Method -> "NeighborhoodContraction"];
{edgeImg, Graphics[{ColorData["DarkRainbow"][RandomReal[]], Line[#]} & /@ 

{enter image description here, enter image description here}


One can observe, FindClusters did not group inner and outer ellipses. How should I tell FindClusters to group inner and outer ellipses? or is there any other alternative?

Note: I would like to keep the question as general as possible that is I would not want to enter the number of clusters explicitly.

Some other images can be as follows:

img1 = URLExecute["https://i.sstatic.net/Z150N.png"];
img2 = URLExecute["https://i.sstatic.net/spkHI.png"];

enter image description here, enter image description here

  • 2
    $\begingroup$ Consider something like FindClusters[edgePoints, 2, Method -> "Agglomerate", CriterionFunction -> "RSquared"]. Playing around with Method and CriterionFunction is worthwhile. $\endgroup$
    – Carl Lange
    Commented May 24, 2019 at 18:50

1 Answer 1


So, you want to find connected components of all edge pixels that are less than N pixels apart?

You could use MorphologicalComponents for this:

MorphologicalComponents[Dilation[edgeImg, 5]]*
  ImageData[edgeImg] // Colorize

enter image description here

  • $\begingroup$ Thanks for the answer. I would like to connect the clustered edge points using Lines too. I have tried this: Graphics[Line@ Position[MorphologicalComponents[Dilation[edgeImg, 5]], 1]], but it gives a black image. Where did I go wrong? $\endgroup$ Commented May 24, 2019 at 19:46
  • $\begingroup$ I realized that points obtained using Position[MorphologicalComponents[Dilation[edgeImg, 5]], 1] are not ordered. Is there a way I could order them? $\endgroup$ Commented May 25, 2019 at 3:30
  • 1
    $\begingroup$ @AnjanKumar: I wouldn't go down that route - there are too many morphological special cases and pitfalls. (Take e.g. the two little line segments at the bottom of the O image above - where would you connect them to?) It's way simpler to use something like MorphologicalPerimeter[img] that is guaranteed to return closed contours than using EdgeDetect and then trying to reconstruct them $\endgroup$ Commented May 25, 2019 at 5:46
  • 2
    $\begingroup$ If you only have a point set and need to find connected components, your best bet is using graph algorithms (see e.g. mathematica.stackexchange.com/questions/95425/…, mathematica.stackexchange.com/questions/80683/…). But as you can see, this is much more complicated than using a function returning closed contours, like ContourDetect, ZeroCrossings or MorphologicalPerimeter $\endgroup$ Commented May 25, 2019 at 5:54
  • 1
    $\begingroup$ So you don't want "clusters" (i.e. sets of connected points), but ordered contours? You could just use ComponentMeasurements[img, "Contours"] for that $\endgroup$ Commented May 25, 2019 at 9:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.