# Clustering edge points of an image?

Consider the following image

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.stack.imgur.com/4q309.png"];
edgeImg = img // EdgeDetect;
edgePoints = PixelValuePositions[edgeImg, 1];
clusteredEdgePoints = FindClusters[edgePoints, Method -> "NeighborhoodContraction"];
{edgeImg, Graphics[{ColorData["DarkRainbow"][RandomReal[]], Line[#]} & /@
clusteredEdgePoints]}


{, }

Question:

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.stack.imgur.com/Z150N.png"];
img2 = URLExecute["https://i.stack.imgur.com/spkHI.png"];


,

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

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


• 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? – Anjan Kumar May 24 '19 at 19:46
• I realized that points obtained using Position[MorphologicalComponents[Dilation[edgeImg, 5]], 1] are not ordered. Is there a way I could order them? – Anjan Kumar May 25 '19 at 3:30
• @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 – Niki Estner May 25 '19 at 5:46
• 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 – Niki Estner May 25 '19 at 5:54
• So you don't want "clusters" (i.e. sets of connected points), but ordered contours? You could just use ComponentMeasurements[img, "Contours"] for that – Niki Estner May 25 '19 at 9:58