Skip to content

Commit 726715b

Browse files
authored
Enable switching automatic tracking model and solver (#1267)
* Enable switching automatic tracking model and solver * Fix iterative prompt generator test assertions * Try to fix BioImage.IO model validation on macOS
1 parent 769bcaf commit 726715b

4 files changed

Lines changed: 33 additions & 7 deletions

File tree

micro_sam/automatic_segmentation.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ def automatic_tracking(
9898
return_embeddings: bool = False,
9999
annotate: bool = False,
100100
batch_size: int = 1,
101+
mode: str = "greedy",
102+
tracking_model: str = "general_2d",
101103
**generate_kwargs
102104
) -> Tuple[np.ndarray, List[Dict]]:
103105
"""Run automatic tracking for the input timeseries.
@@ -120,6 +122,9 @@ def automatic_tracking(
120122
By default, does not activate the annotator.
121123
batch_size: The batch size to compute image embeddings over tiles / z-planes.
122124
By default, does it sequentially, i.e. one after the other.
125+
mode: The trackastra linking solver. One of 'greedy_nodiv', 'greedy' or 'ilp'.
126+
'ilp' uses the motile solver. By default, set to 'greedy'.
127+
tracking_model: The pretrained trackastra model to use. By default, set to 'general_2d'.
123128
generate_kwargs: optional keyword arguments for the generate function of the AMG, APG, or AIS class.
124129
125130
Returns:
@@ -146,6 +151,8 @@ def automatic_tracking(
146151
halo=halo,
147152
verbose=verbose,
148153
batch_size=batch_size,
154+
mode=mode,
155+
tracking_model=tracking_model,
149156
return_embeddings=True,
150157
output_folder=output_path,
151158
**generate_kwargs,

micro_sam/bioimageio/model_export.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,8 @@ def _check_model(model_description, input_paths, result_paths):
221221
# Load outputs.
222222
mask = np.load(result_paths["mask"])
223223

224-
with bioimageio.core.create_prediction_pipeline(model_description) as pp:
224+
# Match the device used to generate the reference outputs.
225+
with bioimageio.core.create_prediction_pipeline(model_description, devices=["cpu"]) as pp:
225226

226227
# Check with all prompts. We only check the result for this setting,
227228
# because this was used to generate the test data.

micro_sam/multi_dimensional_segmentation.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -569,9 +569,9 @@ def _filter_lineages(lineages, tracking_result):
569569
return filtered_lineages
570570

571571

572-
def _tracking_impl(timeseries, segmentation, mode, min_time_extent, output_folder=None):
572+
def _tracking_impl(timeseries, segmentation, mode, min_time_extent, tracking_model="general_2d", output_folder=None):
573573
device = "cuda" if torch.cuda.is_available() else "cpu"
574-
model = Trackastra.from_pretrained("general_2d", device=device)
574+
model = Trackastra.from_pretrained(tracking_model, device=device)
575575
result = model.track(timeseries, segmentation, mode=mode)
576576
try:
577577
lineage_graph, _ = result
@@ -609,6 +609,8 @@ def track_across_frames(
609609
segmentation: np.ndarray,
610610
gap_closing: Optional[int] = None,
611611
min_time_extent: Optional[int] = None,
612+
mode: str = "greedy",
613+
tracking_model: str = "general_2d",
612614
verbose: bool = True,
613615
pbar_init: Optional[callable] = None,
614616
pbar_update: Optional[callable] = None,
@@ -626,6 +628,9 @@ def track_across_frames(
626628
gap_closing: If given, gaps in the segmentation are closed with a binary closing
627629
operation. The value is used to determine the number of iterations for the closing.
628630
min_time_extent: Require a minimal extent in time for the tracked objects.
631+
mode: The trackastra linking solver. One of 'greedy_nodiv', 'greedy' or 'ilp'.
632+
'ilp' uses the motile solver. By default, set to 'greedy'.
633+
tracking_model: The pretrained trackastra model to use. By default, set to 'general_2d'.
629634
verbose: Verbosity flag. By default, set to 'True'.
630635
pbar_init: Function to initialize the progress bar.
631636
pbar_update: Function to update the progress bar.
@@ -650,8 +655,9 @@ def track_across_frames(
650655
segmentation, lineage = _tracking_impl(
651656
timeseries=np.asarray(timeseries),
652657
segmentation=segmentation,
653-
mode="greedy",
658+
mode=mode,
654659
min_time_extent=min_time_extent,
660+
tracking_model=tracking_model,
655661
output_folder=output_folder,
656662
)
657663
return segmentation, lineage
@@ -664,6 +670,8 @@ def automatic_tracking_implementation(
664670
embedding_path: Optional[Union[str, os.PathLike]] = None,
665671
gap_closing: Optional[int] = None,
666672
min_time_extent: Optional[int] = None,
673+
mode: str = "greedy",
674+
tracking_model: str = "general_2d",
667675
tile_shape: Optional[Tuple[int, int]] = None,
668676
halo: Optional[Tuple[int, int]] = None,
669677
verbose: bool = True,
@@ -685,6 +693,9 @@ def automatic_tracking_implementation(
685693
gap_closing: If given, gaps in the segmentation are closed with a binary closing
686694
operation. The value is used to determine the number of iterations for the closing.
687695
min_time_extent: Require a minimal extent in time for the tracked objects.
696+
mode: The trackastra linking solver. One of 'greedy_nodiv', 'greedy' or 'ilp'.
697+
'ilp' uses the motile solver. By default, set to 'greedy'.
698+
tracking_model: The pretrained trackastra model to use. By default, set to 'general_2d'.
688699
tile_shape: Shape of the tiles for tiled prediction. By default prediction is run without tiling.
689700
halo: Overlap of the tiles for tiled prediction. By default prediction is run without tiling.
690701
verbose: Verbosity flag. By default, set to 'True'.
@@ -715,6 +726,8 @@ def automatic_tracking_implementation(
715726
segmentation=segmentation,
716727
gap_closing=gap_closing,
717728
min_time_extent=min_time_extent,
729+
mode=mode,
730+
tracking_model=tracking_model,
718731
verbose=verbose,
719732
output_folder=output_folder,
720733
)

test/test_prompt_generators.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -176,9 +176,14 @@ def _deform_labels(labels):
176176

177177
self.assertTrue(agree.all())
178178

179-
# the condition only holds if we have a negative area (prediction mask where we don't have true mask)
180-
if ((pred_mask - mask) > 0).sum() > 0:
181-
self.assertTrue(diff.all())
179+
# Positive and negative prompts correct false-negative and false-positive regions, respectively.
180+
has_false_negatives = ((mask - pred_mask) > 0).any()
181+
has_false_positives = ((pred_mask - mask) > 0).any()
182+
183+
if has_false_negatives:
184+
self.assertTrue(diff[0])
185+
if has_false_positives:
186+
self.assertTrue(diff[1])
182187

183188

184189
if __name__ == "__main__":

0 commit comments

Comments
 (0)