17

I have a picture like this

enter image description here

I can get this graph's vertexes

mor = MorphologicalBinarize[img // ColorNegate] // 
     DeleteSmallComponents // ColorNegate // MorphologicalComponents;
selectmor = 
  SelectComponents[
    mor, {"AreaRadiusCoverage", "Count"}, # > 0.78 && #2 < 1000 &] // 
   Image;
mask = Graphics@
  Point@ComponentMeasurements[selectmor, "Centroid"][[All, 2]]

enter image description here

Or get its edges

fillimg = 
  FillingTransform[
     MorphologicalBinarize[img // ColorNegate] // 
        DeleteSmallComponents // Thinning // Pruning, 
     selectmor // Binarize] // Thinning // Pruning;
lines = ImageLines[fillimg, MaxFeatures -> 200, 
   Method -> {"Hough", "Segmented" -> True}];
Graphics[{Thick, Red, Line /@ lines}]

enter image description here

This my current work. May be you can realize it by more smart method. My target is not a Image but a Graph. So how to rebuild the Graph by this vertex and this edge?


Update: After the M.R.'s comments (Thanks for your comment), we can use the MorphologicalGraph to get the embryo of graph.

fillimg // MorphologicalGraph[#, VertexLabels -> "Name"] &

enter image description here

But it have a low precision. So How to refine it?

yode
  • 26,686
  • 4
  • 62
  • 167
  • 1
    This has been asked before I believe, check out this answer: http://mathematica.stackexchange.com/questions/6774/is-there-a-way-to-convert-an-image-into-a-graph/6787#6787 – M.R. Dec 17 '15 at 07:27
  • And http://mathematica.stackexchange.com/questions/8935/how-to-convert-an-image-to-a-graph-and-get-the-positions-of-the-edges – M.R. Dec 17 '15 at 07:28
  • 1
    @M.R. Thanks for your MorphologicalGraph in your link.But its precision is very poor when I try to do it.It will introduce many superfluous vertex. – yode Dec 17 '15 at 08:19
  • 2
    @M.R. After I read all your related links,I think this problem is a essential question still. – yode Dec 17 '15 at 08:22
  • Updates to questions are a mean for clarifying them, not for scope drifting – Dr. belisarius Dec 18 '15 at 13:12
  • @Dr.belisarius I'm sorry.You are right.I should maintain the acceptance.My cancel just for attracting more people to solve it.So do you mean I should post another question? – yode Dec 18 '15 at 13:17
  • Oh, you misunderstood me. The problem isn't the acceptance, but that people who already visited your question won't probably come again just to read some clarification. So this way you lose (instead of gain) audience – Dr. belisarius Dec 18 '15 at 13:22
  • @Dr.belisarius Thanks.I think I need a new p by the line's gradient to judge the relation of two vertexes.But I cost an afternoon of time and fail to it. – yode Dec 18 '15 at 13:30
  • @yode Post another question! – Dr. belisarius Dec 18 '15 at 13:40
  • @Dr.belisarius Poor English.But I post it just now. – yode Dec 18 '15 at 14:14

1 Answers1

22
i       = Binarize@Import["https://i.stack.imgur.com/qofeF.png"];
vertexI = SelectComponents[i, "Count", 10 < # < 100 &];
vxPos   = ComponentMeasurements[vertexI, "Centroid"];
lines   = Subsets[Range@Length@vxPos, {2}];
linePos = lines /. vxPos;
ti@x_  := Total@Flatten@ImageData@Binarize@x

p = Position[ti@i - ti@Show[i, Graphics@Line@#] & /@ linePos, x_ /; x < 100];

Graphics[{Red, Line[Extract[linePos, p]]}]

Mathematica graphics

Graph[Range@Length@vxPos, UndirectedEdge @@@ Extract[lines, p], 
      VertexLabels -> "Name", ImagePadding -> 20, 
      VertexCoordinates -> vxPos]

Mathematica graphics

Dr. belisarius
  • 115,881
  • 13
  • 203
  • 453