18
$\begingroup$

I am trying to measure segment length and branch angle or bifurcation angle between each pair of segments.

My image after thinning looks like this:

enter image description here

 i = Import@"http://dl.dropbox.com/u/68983831/thinned.png";
 dat = ImageData[i]; 
 i1 = Image[dat[[34 ;; 242, 28 ;; 213]]]
 g = MorphologicalGraph[i1, EdgeWeight -> Automatic]

thus output looks like:

enter image description here

$\endgroup$
  • 1
    $\begingroup$ The image you uploaded does not give that graph if you plug it in MorphologicalGraph. Please give original image. $\endgroup$ – Vitaliy Kaurov Sep 20 '12 at 23:40
  • 1
    $\begingroup$ There is a range of possible interpretations of the "bifurcation angle," depending on how closely one focuses in on each vertex. At high magnification, all angles must be multiples of 45 degrees, for instance. At the lowest magnification we might elect to draw straight line segments between vertices and use the angles at which they meet, even though these angles might differ greatly from the correct local angles. One idea that allows some control is to intersect a small disk around each vertex with the image and use the relative areas of the black sectors in the disk to estimate the angles. $\endgroup$ – whuber Sep 20 '12 at 23:47
17
$\begingroup$

-------------- Length --------------

Imagine you got an image called img that gives you your morphological graph. Visualize approximately where your vertices are in terms of the pixel coordinates:

g = MorphologicalGraph[img, VertexLabels -> Placed["Name", Center], 
  PlotRangePadding -> 15, Frame -> True, FrameTicks -> All, 
  VertexSize -> .4, VertexStyle -> Yellow, GridLines -> Automatic, 
  AspectRatio -> Automatic]

enter image description here

Get vertex coordinates:

vc = AbsoluteOptions[g, VertexCoordinates]

VertexCoordinates -> {{107.5, 139.5}, {87.5, 105.5}, {131.5, 115.5}, {112.5, 87.5}, {55.5, 86.5}, {27.5, 99.5}, {115.5, 67.5}, {59.5, 11.5}}

Realize relationships between vertex coordinates and vertex labels:

vcl = Sort[Rule @@@ Transpose[{VertexList[g], vc[[2]]}]]

{1 -> {107.5, 139.5}, 2 -> {131.5, 115.5}, 3 -> {87.5, 105.5}, 4 -> {27.5, 99.5}, 5 -> {112.5, 87.5}, 6 -> {55.5, 86.5}, 7 -> {115.5, 67.5}, 8 -> {59.5, 11.5}}

Get legthes of edges in terms of pixel coordinates:

el = {#, EuclideanDistance[vcl[[#1, 2]], vcl[[#2, 2]]] & @@ #} & /@ EdgeList[g]

{{1 [UndirectedEdge] 3, 39.4462}, {2 [UndirectedEdge] 5, 33.8378}, {3 [UndirectedEdge] 5, 30.8058}, {3 [UndirectedEdge] 6, 37.2156}, {4 [UndirectedEdge] 6, 30.8707}, {5 [UndirectedEdge] 7, 20.2237}, {6 [UndirectedEdge] 8, 75.1066}}

Grid[el, Frame -> All]

enter image description here

Visualize as labels:

elg = Graph[EdgeList[g], vc, EdgeLabels -> Rule @@@ el, 
  GraphStyle -> "ThickEdge", VertexLabels -> "Name", 
  VertexLabelStyle -> Directive[Red, Bold, 18], PlotRangePadding -> 10]

enter image description here

-------------- Angle --------------

Define some functions. Turn a single edge into a pair of its vertex coordinates:

ctp[x_] := {#[[1, 2]], #[[2, 2]]} &@(vcl[[#]] & /@ (x))

Slope based on 2 points:

sl[{a_, b_}] := Divide @@ Reverse[a - b]

Angle based on 2 slopes:

ang[{a_, b_}] := ArcTan[Abs[(sl[ctp@a] - sl[ctp@b])/(1 + sl[ctp@a] sl[ctp@b])]]

According to the 1st picture in my post your branching vertexes are {6,3,5}, so here you go with angles in degrees (where 1st column is triple of vertices labeling the angle):

data = {Union[{#[[1, 1]], #[[1, 2]], #[[2, 1]], #[[2, 2]]}], 
     180 - 180/Pi ang[#]} & /@ Flatten[Partition[#, 2, 1, 1] & /@ 
     EdgeList /@ (NeighborhoodGraph[g, #] & /@ {6, 3, 5}), 1];

Grid[data, Frame -> All]

enter image description here

Compute centers of triangles and place the angle labels stylized in blue:

la[x_] := Text[Style[x[[2]], Blue, Italic], Mean[vcl[[#, 2]] & /@ x[[1]]]]

Show[Graphics[la /@ data], elg]

enter image description here

$\endgroup$
10
$\begingroup$
thin = Import@"http://i.stack.imgur.com/me0gY.jpg";
thin = Dilation[thin, 3];
g = MorphologicalGraph[thin, VertexLabels -> "Name", ImagePadding -> 10]

Mathematica graphics

For the vertex |5|

vc = PropertyValue[{g, #}, VertexCoordinates] & /@ Sort@VertexList[g];
vcOff = # - vc[[5]] & /@ vc;
vectors = Extract[vcOff, List /@ Cases[EdgeList[g], _[x_, 5] | _[5, x_] -> x]];
Graphics[Line[{{0, 0}, #}] & /@ vectors, Axes -> True]

Mathematica graphics

And the angles can be obtained by

Mod[Subtract[#[[1]], #[[2]]], 2 Pi] & /@ Partition[ArcTan @@@ 
                                  Join[vectors, vectors[[1 ;; 1]]], 2, 1]
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy