# Segmenting a binary image into three parts

I am trying to segment a binary image into three parts, head, body, and tail. The binary image is a stack of tiff files of a moving fruit fly larvae. I was able to do this initially by removing points within a certain distance of the centroid:

However, this broke down when the larvae's head moved too close to the centroid, because the head points would then be removed:

I have been looking for creative solutions to this problem. Trying to fit it to a curved ellipsoid and get the vertice points that make up the tail and the head. However, I have not been very successful! I was curious if anyone had any insight into this problem or a suggestion for a creative solution?

Here are the raw binary images:

1)

2)

• Hm. MorphologicalGraph does a fairly good job to identify the ends of the larvae (try Show[img, MorphologicalGraph[img]]). But it is far from perfect... Commented Sep 27, 2020 at 19:00
• Thank you for the suggestion! I will play around with that. I tried a SkeletonTransform into a Binarization but the branching points were interfering. I tried a prune but that was truncating the furthest endpoints. Commented Sep 27, 2020 at 19:06
• Yes, SkeletonTransform was also one of my first guesses. And indeed, there is too much artificial branching going on... =/ Commented Sep 27, 2020 at 19:12
• Using the MorphologicalGraph function I have managed to get the vertex coordinates in each frame. I am running into the issue now that there are more than 2 vertex coordinates. I am thinking to narrow this down to use the EuclideanDistance function to find the points that have the greatest distance between them and take that but does not appear that this solution will work for every case. Commented Sep 27, 2020 at 22:02

The best answer I could manage is to use the following:

1. First I got the vertices using MorphologicalGraph function:
     AbsoluteOptions[MorphologicalGraph[myBinMovie[[frame]]], VertexCoordinates]


1. Sometimes, this would give me more than two vertices so I used an If function to find the furthest two vertices based on the EuclideanDistance function:
      myMaxDisVerts =Table[If[Length@myVertices[[frame, 1, 2]] == 2,
myVertices[[frame, 1, 2]],
myTempMaxDis =
Max /@ Table[
EuclideanDistance[myVertices[[frame, 1, 2, i]],
myVertices[[frame, 1, 2, j]]], {i, 1,
Length@myVertices[[frame, 1, 2]], 1}, {j, 1,
Length@myVertices[[frame, 1, 2]], 1}];
myVertices[[frame, 1, 2,
Flatten@Position[myTempMaxDis, Max[myTempMaxDis]]]]], {frame, 1,
Length@myVertices, 1}]

1. Using these points, I then took the closest 70 pixels that were a value of 1 from the Binary image using the ReplacePixelValue function:
    Table[ReplacePixelValue[
Flatten[Table[(NearestTo[myMaxDisVerts[[frame, j]],
test6[[frame]]]), {j, 1, Length@myMaxDisVerts[[frame]], 1}],
1] -> 1], {frame, 1, Length@myMaxDisVerts, 1}];


1. I then took the centroid of these Binary images that made up the "head" and "tail" of the larvae using ComponentMeasurements and found their closest neighbors through each frame:
    myNearestHTPosCentroid =
ComponentMeasurements[#, "Centroid"] & /@ myNearestHTPos;

1. Plotted the centroid and the head and tail points joined points with the original movie:
    myCentroidJoinedLarvaColMovie =