Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I have been trying to find a way to separate the various closed paths that can be output by EdgeDetect. For example, taking the output of:

ColorNegate@EdgeDetect@Graphics[Style[Text["8"], 400]]

enter image description here

I'd like to be able to obtain a list like:

enter image description here

I'd really love to show some progress I made on this, but to be honest, I'm stuck at the beginning. I really don't know how to attack this one. The naïve approach might be to take one black pixel, then go around it registering adjacent pixels as part of the same path, while erasing them from the original image. But I don't expect this to be anything other than painfully slow, and there probably are some Mathematica image manipulation functions that I could leverage. So, how would you advise me to start?

share|improve this question
2  
@ F'x This question seems very close to this one: mathematica.stackexchange.com/questions/637/… Perhaps the same method would work. –  R Hall Apr 14 '12 at 15:52
add comment

4 Answers

up vote 12 down vote accepted

You can use MorphologicalComponents to get the different loops:

With[{components = MorphologicalComponents@EdgeDetect@Graphics[Style[Text["8"], 400]]},
    ColorNegate@Image[1 - Unitize[components - #]] & /@ Range[Max[components]]]

enter image description here

Trying this on other similar characters — {"A", "B", "g", "9"}

enter image description here

share|improve this answer
add comment

While R.M. and belisarius answers certainly work, they seem a bit complex for me, extracting separate masks out of MorphologicalComponents's output. It gets a lot simpler if you use ComponentMeasurements instead, which simply returns a list of masks for each component (as sparse arrays, so might be more efficient, too):

edges = EdgeDetect@Graphics[Style[Text["8"], 400]]; (* taken from belisarius's answer *)
masks = ComponentMeasurements[edges, "Mask"];
Image /@ masks[[All, 2]]
share|improve this answer
add comment

This is partly derived from Vitaliy answer here.

pic = 
  Thinning@
   Binarize[
    GradientFilter[
     Rasterize[Style["8", FontFamily -> "Times"], ImageSize -> 500] //
       Image, 1]];
pdata = Position[ImageData[pic, DataReversed -> True]\[Transpose], 1];
lcp = ListCurvePathPlot[pdata, Axes -> None]

My only change is the massaging to get the '8' upright.

Mathematica graphics

Now it's pretty easy to get the paths from it:

Graphics /@ Cases[lcp, Line[a_], Infinity]

Mathematica graphics

share|improve this answer
add comment

In the same spirit as RM's answer

mc = MorphologicalComponents[EdgeDetect@Graphics[Style[Text["8"], 400]]];
Image /@ (Array[Replace[mc, {{Except[#] -> 0}}, {2}] &, Max@mc][[All, 1]])

enter image description here

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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