3
$\begingroup$

I have a video of worm-like objects which move. They can move in a straight line, they can rotate in circles, they can move in a serpentine/winding/sinuous way. I need to track them.

I already have all the necessary code to track them by finding their contours so I have all the "topological" information necessary however there is one last thing I am not able to do so far: finding their center.

What I mean by center is of course not the center of mass or of gravity or of simmetry, but rather the mid-point, the center along the line that goes from head to tail.

I need it because if the worm rotates or steers, the center-of-mass does not move much but the mid-point of the worm is actually moving.

Does abybody have any suggestion?

Here an example of the kind of images we are dealing with:

enter image description here enter image description here

$\endgroup$
8
  • $\begingroup$ What an interesting problem! Are they always going to be just a couple of pixels wide, like your example? What level of accuracy is required, is being off by one or two pixels close enough? $\endgroup$ Mar 22, 2018 at 11:29
  • $\begingroup$ Are you able to determine which are the two end points? $\endgroup$ Mar 22, 2018 at 20:24
  • $\begingroup$ They won't be much wider than that, not more than 5 pixels. Accuracy is not a big problem... I have the contour of the object i.e. the coordinates of the border and of the points inside. I can't Think of and smart way to find the two ends right now but in principle it should be possible $\endgroup$
    – JalfredP
    Mar 23, 2018 at 7:43
  • $\begingroup$ @CrisLuengo, Do you have something like MATLAB's bwskel() in your library? $\endgroup$
    – Royi
    Jun 30, 2023 at 12:07
  • 1
    $\begingroup$ @Royi Yes, it’s called EuclideanSkeleton. $\endgroup$ Jun 30, 2023 at 14:00

1 Answer 1

1
$\begingroup$

This is a nice question.

The trick to solve it, in the path I took, is creating a skeleton from the chain.
This is the algorithm I came up with:

  1. Create the Skeleton
    I used MATLAB's bwskel().
    It creates a chain where each pixel has 2 connected pixels.
  2. Find the Boundary of the Chain
    In order to find the starting point I convolved the skeleton with a matrix $\begin{bmatrix} 1 & 1 & 1 \\ 1 & 0 & 1 \\ 1 & 1 & 1 \end{bmatrix}$. Then masked the result with the skeleton and looked for pixels which have a single neighbor.
  3. Walking Over the Chain
    Since each pixel has 2 pixels connected, there is a single way of direction which is not the way we got to the pixel.
    So for each pixel we're looking for a neighbor we didn't come from.
    This way we go over the chain until we reach the other boundary.
    At each step we keep the step index and the coordinates.
    At the end of the loop, we have the number of elements and the index of each. We extract the middle of this.

The results:

enter image description here

enter image description here

enter image description here

The code is available at my StackExchange Codes Signal Processing GitHub Repository (Look at the SignalProcessing\Q48008 folder).

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.