Hi Natash,
I think you would rather need ImageMesh
:
img = Binarize@
Import["https://community.wolfram.com//c/portal/getImageAttachment?filename=ske3.png&userId=1555685"];
mesh = ImageMesh[img]
From this BoundaryMeshRegion
line segments can be extracted (and viewed):
lines = MeshPrimitives[mesh, 1];
Manipulate[
Graphics[lines[[;; n]], PlotRange -> {{0, 550}, {0, 160}}], {n, 1, Length[lines], 1}]
Obviously this structure is regarded as a two dimensional thing, and consequently the lines describe its boundary (and appear to run around twice ...). Furthermore some elements of the image border were detected.
But it should not be difficult to select the needed parts.
Does that help? Regards -- Henrik
Addendum/Edit:
Here comes a better solution: I start by cleaning up you original image by padding, then I calculate the positions of the white pixels. The problem now is that they are not ordered along a line. This can be improved by using FindShortestTour
. Now the problem is that this gives a single line and there are necessarily jumps.
img1 = ImagePad[img, -1];
pixelPos = PixelValuePositions[img1, 1];
order = Last[FindShortestTour[pixelPos]];
Graphics[Line[pixelPos[[order]]]]
But with a little effort those long distances between two successive points can be detected and eliminated (... most likely there is a more elegant way of doing this):
longLineIndex =
Select[MapIndexed[{First[#2], EuclideanDistance @@ #1} &,
Partition[pixelPos[[order]], 2, 1]], Last[#] > 10 &][[All, 1]];
lineSequenceIndex = Partition[Join[{1}, longLineIndex, {Length[order]}], 2, 1];
lineSequenceIndex = Join[{lineSequenceIndex[[1]]}, {#1 + 1, #2} & @@@ lineSequenceIndex[[2 ;;]]];
cleanLinePoints = pixelPos[[order]][[Span @@ #]] & /@ lineSequenceIndex;
Graphics[BezierCurve /@ cleanLinePoints]