In case you want EVERY point on edges, this is my implementation:
img = Binarize[Import["https://i.stack.imgur.com/cET4A.png"] // Thinning];
The pointSetImg
stores all vertexes in the image img
:
pointSetImg = ImageAdd @@ (MorphologicalTransform[img, #1] & ) /@
{"SkeletonEndPoints", "SkeletonBranchPoints"};
By subtracting pointSetImg
from img
, imge with all edges separated is obtained:
edgeSetImg = ImageSubtract[img, Dilation[pointSetImg, DiskMatrix[1]]];
Separate every connected image component:
edgeSeparatedArray = MorphologicalComponents[edgeSetImg];
Now edgeSeparatedArray
is a ImageData
-like array with each connected component represented by a unique integer:
Tally[Flatten[edgeSeparatedArray]] // Shallow
{{0, 1429814}, {1, 65}, {2, 100}, {3, 6}, {4, 26}, {5, 1}, {6,
65}, {7, 57}, {8, 3}, {9, 27}, <<370>>}
So for example you want the coordinates of points of the sixth edge, you can do this:
Position[edgeSeparatedArray, 6]
{{137, 934}, {138, 934}, {139, 934}, {140, 934}, {141, 934}, {142,
934}, {143, 934}, {144, 934}, {145, 934}, {146, 933}, {147,
933}, {148, 933}, {149, 933}, {150, 933}, {151, 933}, {152,
933}, {153, 932}, {154, 932}, {155, 932}, {156, 932}, {157,
931}, {158, 931}, {159, 931}, {160, 931}, {161, 930}, {162,
930}, {163, 930}, {164, 930}, {165, 929}, {166, 929}, {167,
929}, {168, 929}, {169, 929}, {170, 929}, {171, 929}, {172,
929}, {173, 929}, {174, 929}, {175, 929}, {176, 929}, {177,
929}, {178, 930}, {179, 930}, {180, 930}, {181, 930}, {182,
930}, {183, 930}, {184, 930}, {185, 930}, {186, 930}, {187,
930}, {188, 930}, {189, 931}, {190, 931}, {191, 931}, {192,
931}, {193, 931}, {194, 931}, {195, 930}, {196, 930}, {197,
930}, {198, 930}, {199, 929}, {200, 929}, {201, 929}}
Show all edges in an image:
edgeSeparatedArray // Colorize

Note: There may be some vertexes get too close that the ImageSubtract
erasures the edges between them completely. In that case you may want to ImageResize
you original image before go through all the above process.
Update:
As OP asks for a function which takes any two vertex as input and output the points on the edge between them (if any), my implementation is following:
Obtain the separated vertexes image and count the number of vertexes:
pointDilatedSeparatedArray = MorphologicalComponents[pointSetImgDilated];
vertexSetSize = Max[Tally[Flatten[pointDilatedSeparatedArray]][[All, 1]]]
274
Define function edgeForVertexFunc
which takes No. of vertex as input and output the No.s of all edges connecting to the correspond vertex:
edgeForVertexFunc = Compile[{
{vertexNum, _Integer},
{pointDilatedSeparatedArray, _Integer, 2},
{edgeSeparatedArray, _Integer, 2}},
Module[{rowm, rowM, colm, colM},
{{rowm, rowM}, {colm, colM}} = Sort[#][[{1, -1}]] & /@
(Position[pointDilatedSeparatedArray, vertexNum]\[Transpose]);
edgeSeparatedArray[[rowm - 1 ;; rowM + 1, colm - 1 ;; colM + 1]] //
Flatten // Union // Complement[#, {0}] &
],
CompilationTarget -> "C", RuntimeOptions -> "Speed"]
Then we use it to obtain edges set for each vertex:
(edgeForVertexSet = edgeForVertexFunc[#,
pointDilatedSeparatedArray, edgeSeparatedArray
] & /@ Range[vertexSetSize])//Shallow
{{3}, {1, 3, 4}, {5}, {2, 5, 6}, {7}, {8}, {4, 8, 9}, {1, 10, 11}, {2,
12, 13}, {11, 14, 15}, <<264>>}
Define function coordPickFunc
for extracting "coordinates" (row- and column-indices) of n
in some SeparatedArray
:
coordPickFunc =
Compile[{{n, _Integer}, {SeparatedArray, _Integer, 2}},
Position[SeparatedArray, n], CompilationTarget -> "C",
RuntimeOptions -> "Speed"]
Function edgeNumBetweenVertex
for finding No. of common edge between vertex i
& j
, and function edgeCoordBetweenVertex
and vertexCoord
for extracting coordinates:
edgeNumBetweenVertex[i_, j_] :=
Intersection[edgeForVertexSet[[i]], edgeForVertexSet[[j]]]
edgeCoordBetweenVertex[i_, j_] :=
If[# == {}, {}, coordPickFunc[#[[1]], edgeSeparatedArray]] &[edgeNumBetweenVertex[i, j]]
vertexCoord[i_] := Mean[coordPickFunc[i, pointDilatedSeparatedArray]]
Applications
There is no edge between 5-th and 7-th vertexes:
edgeCoordBetweenVertex[5, 7]
{}
The coordinates of 13-rd and 32-nd vertexes are:
vertexCoord /@ {13, 32}
{{403, 1284}, {544, 1135}}
The edge between them goes through points with coordinates as:
edgeCoordBetweenVertex[13, 32]//Shallow
{{405, 1282}, {406, 1281}, {407, 1280}, {408, 1279}, {409,
1278}, {410, 1277}, {411, 1276}, {412, 1275}, {413, 1274}, {414,
1271}, <<146>>}
Show it on graphics:
edgeSetImg // ImageData // ArrayPlot[#, DataReversed -> True,
Epilog -> {
Blue, Thick, Line[Reverse /@ edgeCoordBetweenVertex[13, 32]],
Red, PointSize[.005], Point[Reverse[vertexCoord@#] & /@ {13, 32}]
}] &

Binarize
the image andPosition
all1
in theImageData
array? $\endgroup$