@@ -76,22 +76,29 @@ def setup_ilastik(model_path: str):
7676
7777def segment_ROI (
7878 input_data : np .ndarray ,
79+ num_labels_tot : dict [str , int ],
7980 shell : Any ,
8081 foreground_class : int = 0 ,
8182 threshold : float = 0.5 ,
8283 min_size : int = 15 ,
8384 label_dtype : Optional [np .dtype ] = None ,
85+ relabeling : bool = True ,
8486) -> np .ndarray :
8587 """Run the Ilastik model on a single ROI.
8688
8789 Args:
8890 input_data: np.ndarray of shape (t, z, y, x, c).
91+ num_labels_tot: Number of labels already in total image. Used for
92+ relabeling purposes. Using a dict to have a mutable object that
93+ can be edited from within the function without having to be passed
94+ back through the masked_loading_wrapper.
8995 shell: Ilastik headless shell.
9096 foreground_class: Class to be considered as foreground
9197 during prediction thresholding.
9298 threshold: Threshold for the Ilastik model.
9399 min_size: Minimum size for the Ilastik model.
94100 label_dtype: Label images are cast into this `np.dtype`.
101+ relabeling: Whether relabeling based on num_labels_tot is performed.
95102
96103 Returns:
97104 np.ndarray: Segmented image. Shape (z, y, x).
@@ -145,6 +152,23 @@ def segment_ROI(
145152 ilastik_labels = label (ilastik_labels )
146153 logger .info (f"number of labels after filtering for size = { ilastik_labels .max ()} " )
147154 label_props = regionprops (ilastik_labels )
155+
156+ # Shift labels and update relabeling counters
157+ if relabeling :
158+ num_labels_roi = np .max (ilastik_labels )
159+ ilastik_labels [ilastik_labels > 0 ] += num_labels_tot ["num_labels_tot" ]
160+ num_labels_tot ["num_labels_tot" ] += num_labels_roi
161+
162+ # Write some logs
163+ logger .info (f"ROI had { num_labels_roi = } , { num_labels_tot = } " )
164+
165+ # Check that total number of labels is under control
166+ if num_labels_tot ["num_labels_tot" ] > np .iinfo (label_dtype ).max :
167+ raise ValueError (
168+ "ERROR in re-labeling:"
169+ f"Reached { num_labels_tot } labels, "
170+ f"but dtype={ label_dtype } "
171+ )
148172
149173 return ilastik_labels .astype (label_dtype )
150174
@@ -166,6 +190,7 @@ def ilastik_pixel_classification_segmentation(
166190 use_masks : bool = True ,
167191 # Ilastik-related arguments
168192 ilastik_model : str ,
193+ relabeling : bool = True ,
169194 foreground_class : int = 0 ,
170195 threshold : float = 0.5 ,
171196 min_size : int = 15 ,
@@ -197,6 +222,8 @@ def ilastik_pixel_classification_segmentation(
197222 loading is relevant when only a subset of the bounding box should
198223 actually be processed (e.g. running within `emb_ROI_table`).
199224 ilastik_model: Path to the Ilastik model (e.g. `"somemodel.ilp"`).
225+ relabeling: If `True`, apply relabeling so that label values are
226+ unique for all objects in the well.
200227 foreground_class: Class to be considered as foreground during
201228 prediction thresholding.
202229 threshold: Probabiltiy threshold for the Ilastik model.
@@ -385,9 +412,13 @@ def ilastik_pixel_classification_segmentation(
385412
386413 # Initialize other things
387414 logger .info (f"Start ilastik pixel classification task for { zarr_url } " )
415+ logger .info (f"relabeling: { relabeling } " )
388416 logger .info (f"{ data_zyx .shape } " )
389417 logger .info (f"{ data_zyx .chunks } " )
390418
419+ # Counters for relabeling
420+ num_labels_tot = {"num_labels_tot" : 0 }
421+
391422 # Iterate over ROIs
392423 num_ROIs = len (list_indices )
393424
@@ -433,10 +464,12 @@ def ilastik_pixel_classification_segmentation(
433464 # Prepare keyword arguments for segment_ROI function
434465 kwargs_segment_ROI = {
435466 "shell" : shell ,
467+ "num_labels_tot" : num_labels_tot ,
436468 "foreground_class" : foreground_class ,
437469 "threshold" : threshold ,
438470 "min_size" : min_size ,
439471 "label_dtype" : label_dtype ,
472+ "relabeling" : relabeling ,
440473 }
441474
442475 # Prepare keyword arguments for preprocessing function
0 commit comments