TrackMate: dynamic filtering of spots after detection, before tracking

I aim to automatically track spots in relatively noisy time series, where:

  • I’d like to adjust the spot quality threshold in function of time, i.e. decrease the threshold for later time frames, when fluorophores are weaker due to bleaching.

  • I’d like to filter the spots with a given binary mask resulting from a previous segmentation. I tried to convert the mask into a Roi, but because TrackMate uses roi.getPolygon() (see this line), this approach won’t work when my mask results in a disconnected ROI (the polygon of an instance of ij.gui.ShapeRoi is its bounding box, not the actual shape).

My approach would be to:

  1. detect spots with a low threshold, then

  2. filter the spots according to a combination of Spot.POSITION_T and Spot.QUALITY to achieve a “dynamic” threshold,

  3. use a RandomAccess on my mask image to filter the spots if their x,y,z position corresponds to a masked image area

  4. use the (Simple) LAP Tracker on my custom-filtered spot collection to generate my final tracks.

While I know more or less how to achieve steps 1-3 above to get the desired spot collection, I’m unsure on how to best invoke the LAP tracker on this spot collection (step 4 above). I can create and process a new tracker instance like this:

SpotTracker tracker = new SparseLAPTracker( spotCollection, settings);
boolean success = tracker.process()

But how can I get a list of spot IDs with linked track IDs from this?

I had the impression that the approach outlined on the Scripting TrackMate page doesn’t allow for enough flexibility to do what I want.

@tinevez et al: would you have some examples of doing this? or some other comments on the sketched workflow?


Hi @imagejan

Unfortunately, no I do not have a working example of what you describe.

*1. & 2.
As you noted correctly, the threshold is absolute and scale with the input image intensity. So when this intensity decreases because of bleaching, the threshold does not scale.
When I met this issue I resolved to either

  • manually correct for mistakes (C. elegans)
  • normalize the input image so that the intensity has constant min and max for all time-points.
    None of this is satisfying as you cannot really make up for image data with decaying SNR.

As for the Roi-based spot exclusion, you are right, I use the polygon, which cannot handle properly arbitrary shapes. Do you have of a workaround that would harness all IJ rois? We would change TrackMate to implement it.

I submitted a pull request to allow for instances of ij.gui.ShapeRoi to be processed correctly. Ideally, I would have removed the settings.polygon field altogether in favor of a settings.roi field, but I didn’t want to break backwards compatibility with existing scripts (settings.polygon is public).

(This way we can also avoid bumping the version to TrackMate 4.0, can we? ;-))

Also, I was a bit confused about the duplicated code in doing the pruning of the spot collection that appears in the translateAndPruneSpots method:

as well as in the execDetection method:

But I think I covered all cases here.

@tinevez thanks for merging!

Regarding spot filtering: for a slightly different use case, I needed a way to keep only the best spot in each frame (when tracking a single locus over time, i.e. each frame contains at most one “real” spot), so I implemented a Max Quality Spot Analyzer:

@tinevez If you think it might be useful to others, I am happy to contribute it to any repository you suggest.

Also, is there an overview on third-party contributions to TrackMate somewhere? Should I add a note to Maybe trackmate-extras and trackmate-examples can be featured there more prominently as well?


Is there any change I could make some comments on the analyzer? Only minor stuff.

As for making it public, you are right: The proper way is through the extension paragraph in the TrackMate wiki page.

But right now this section is a mess. Everything is misses, and you actually want to let the user download a compiled .jar file instead of linking to the source. Time time time… :frowning:

1 Like

Sure, I’d be glad to get some feedback on this! Do you just want to comment on the PR I just opened?

Alright, I’ll edit this page then.