Skip to content

feat(nii): add bounding-box-chain connected-component filter - #143

Merged
Hendrik-code merged 3 commits into
mainfrom
feat/nii-bbox-chain-filter
Aug 28, 2026
Merged

feat(nii): add bounding-box-chain connected-component filter#143
Hendrik-code merged 3 commits into
mainfrom
feat/nii-bbox-chain-filter

Conversation

@Hendrik-code

Copy link
Copy Markdown
Owner

Upstreams B13 (and A19's overlap_slice) from the cross-repo survey.

What

np_utils

  • np_slices_overlap(slice1, slice2) — do two ranges overlap or touch? Borders count.
  • np_filter_connected_components_by_bbox_chain(arr, margin, extra_margin, extra_margin_axis, connectivity) — the array core.

NII

  • filter_connected_components_by_bbox_chain(margin_mm=0.0, extra_margin_mm=0.0, extra_margin_axis=None, …) — the mm-aware wrapper.

Starting from the largest connected component, any component whose margin-grown bounding box overlaps the growing region on every axis is kept, repeating until nothing new is added. Everything else is dropped, and the labels of kept voxels are preserved.

This is the "keep the spine, drop the unrelated blobs" filter: a structure fragmented into several pieces along its length survives, while a component off to the side does not.

seg.filter_connected_components_by_bbox_chain(margin_mm=4.0)
seg.filter_connected_components_by_bbox_chain(extra_margin_mm=8.0, extra_margin_axis="I")  # tolerate gaps along the spine

Ported from

spineps/spineps/phase_semantic.pysemantic_bounding_box_clean and overlap_slice.

Changes from the original

  • Margins are physical. The original converted mm to voxels using min(zoom) for every axis; this converts per axis, so the region grows by the same physical distance on anisotropic data. A test pins this: at 4 mm slice spacing, a 4 mm margin spans one voxel and correctly fails to close a 6-voxel gap.
  • The extra-margin axis is a parameter, rather than hardcoded to inferior.
  • Bounding boxes come from np_bounding_boxes in one pass, instead of an extract_label() + compute_crop() loop over every component.
  • Dropped the logger and the MAX_EXPECTED_SEMANTIC_CC warning, per the survey note.
  • Dropped a redundant step. The original intersected the result with the union bounding box of the incorporated components before masking by component membership. That cannot change the outcome — each incorporated component already lies inside its own box — so only the membership mask remains.

Verification

  • 10 new tests in unit_tests/test_nii_extended.py: zero-margin keeps only the anchor; a margin chains across gaps while still excluding the outlier; extra margin applies only to its own axis; a large margin reaches everything; margins are physical not voxel; original labels are preserved; a single component is untouched; extra_margin_mm without an axis is rejected. Plus overlap/symmetry cases for np_slices_overlap.
  • Full suite: 474 passed, 4 skipped. ruff check clean.

🤖 Generated with Claude Code

Adds np_slices_overlap and np_filter_connected_components_by_bbox_chain to
np_utils, plus NII.filter_connected_components_by_bbox_chain as the mm-aware
wrapper.

Starting from the largest connected component, any component whose
margin-grown bounding box overlaps the growing region on every axis is kept,
repeating until nothing new is added; everything else is dropped. This keeps a
structure fragmented into several pieces along its length while discarding
unrelated blobs elsewhere in the volume.

Ported from spineps semantic_bounding_box_clean, with three changes:
- margins are given in mm and converted per axis from zoom, rather than using
  min(zoom) for every axis, so the region grows by the same physical distance
  on anisotropic data
- the extra-margin axis is a parameter instead of being hardcoded to inferior
- per-label bounding boxes come from np_bounding_boxes in one pass instead of
  an extract_label/compute_crop loop over every component

The original also intersected the result with the union bounding box of the
incorporated components; that step cannot change the outcome, since each
incorporated component already lies inside its own box, so it is dropped.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Aug 27, 2026

Copy link
Copy Markdown

Benchmark comparison

Speed (wall time per call)

baseline e84dbcd vs head e84dbcd · python 3.11.16 · 5 repeats + 1 warmup

Showing the 5 most-changed measurements per case; the rest are collapsed. Rows with a baseline below 3 ms are tagged (noise) — runner jitter on those swamps any real change.

ct_3d — shape (73, 47, 73)

Measurement baseline ms (median ±½·range) head ms (median ±½·range) Δ % p
nii_save 11.87 ±0.06 11.34 ±0.02 -4.5% 0.000
poi_calc_centroids_nocrop 4.08 ±0.02 3.97 ±0.05 -2.5% 0.024
poi_calc_poi_from_subreg_vert 12.25 ±0.07 12.45 ±0.11 +1.7% 0.019
nii_load_img 10.67 ±0.07 10.53 ±0.04 -1.3% 0.004
nii_rescale_seg 3.10 ±0.03 3.08 ±0.04 -0.8% 0.202
… 31 more measurements
Measurement baseline ms (median ±½·range) head ms (median ±½·range) Δ % p
nii_erode_msk 6.00 ±0.02 5.96 ±0.06 -0.6% 0.183
nii_resample_from_to 41.30 ±0.23 41.52 ±0.12 +0.5% 0.019
nii_dilate_msk 121.92 ±1.47 121.28 ±0.48 -0.5% 0.263
nii_rescale 39.37 ±0.14 39.27 ±0.07 -0.3% 0.279
nii_fill_holes 4.32 ±0.01 4.32 ±0.04 -0.0% 0.776
nii_filter_connected_components 4.08 ±0.03 4.08 ±0.03 -0.0% 0.721
metric_voxels 250463.00 ±0.00 250463.00 ±0.00 +0.0%
metric_labels 3.00 ±0.00 3.00 ±0.00 +0.0%
metric_foreground_pct 14.51 ±0.00 14.51 ±0.00 +0.0%
nii_compute_crop 0.26 ±0.01 0.32 ±0.02 +22.2% (noise) 0.003
nii_get_array 0.04 ±0.00 0.03 ±0.01 -21.1% (noise) 0.179
poi_save 0.33 ±0.02 0.40 ±0.03 +19.7% (noise) 0.005
nii_extract_label 0.29 ±0.02 0.35 ±0.01 +18.6% (noise) 0.003
poi_map_labels 0.14 ±0.01 0.16 ±0.02 +17.6% (noise) 0.018
nii_apply_crop 0.51 ±0.02 0.59 ±0.04 +16.0% (noise) 0.002
nii_pad_to 0.50 ±0.02 0.57 ±0.04 +15.4% (noise) 0.008
poi_resample_from_to 0.56 ±0.03 0.63 ±0.02 +13.8% (noise) 0.001
nii_map_labels 0.88 ±0.01 0.98 ±0.03 +12.1% (noise) 0.000
nii_unique 0.58 ±0.01 0.64 ±0.03 +10.0% (noise) 0.006
poi_reorient 0.33 ±0.01 0.30 ±0.02 -7.9% (noise) 0.095
nii_load_seg 2.71 ±0.03 2.51 ±0.03 -7.4% (noise) 0.000
poi_load 0.87 ±0.01 0.92 ±0.02 +4.9% (noise) 0.004
nii_get_connected_components 2.09 ±0.07 2.01 ±0.03 -3.7% (noise) 0.065
poi_local_to_global_arr 0.26 ±0.01 0.25 ±0.01 -3.0% (noise) 0.064
nii_center_of_masses 1.66 ±0.01 1.70 ±0.02 +2.3% (noise) 0.005
nii_reorient 0.76 ±0.01 0.78 ±0.04 +2.2% (noise) 0.967
poi_rescale 0.16 ±0.01 0.16 ±0.01 -1.9% (noise) 0.456
nii_volumes 1.77 ±0.01 1.80 ±0.01 +1.8% (noise) 0.001
poi_calc_centroids 2.28 ±0.02 2.24 ±0.02 -1.7% (noise) 0.002
nii_set_dtype 0.43 ±0.01 0.43 ±0.02 -0.5% (noise) 0.670
poi_to_global 0.15 ±0.01 0.15 ±0.01 -0.5% (noise) 0.997

ct_2d — shape (73, 47, 1)

Measurement baseline ms (median ±½·range) head ms (median ±½·range) Δ % p
nii_rescale 5.31 ±0.17 5.04 ±0.08 -5.2% 0.010
nii_resample_from_to 7.50 ±0.08 7.18 ±0.03 -4.3% 0.000
nii_dilate_msk 14.33 ±0.19 14.30 ±0.09 -0.2% 0.333
metric_voxels 3431.00 ±0.00 3431.00 ±0.00 +0.0%
metric_labels 3.00 ±0.00 3.00 ±0.00 +0.0%
… 30 more measurements
Measurement baseline ms (median ±½·range) head ms (median ±½·range) Δ % p
metric_foreground_pct 37.60 ±0.00 37.60 ±0.00 +0.0%
nii_unique 0.10 ±0.00 0.12 ±0.01 +15.7% (noise) 0.003
nii_extract_label 0.36 ±0.01 0.41 ±0.01 +13.8% (noise) 0.000
nii_map_labels 0.42 ±0.02 0.47 ±0.02 +10.3% (noise) 0.002
poi_calc_centroids 0.85 ±0.03 0.93 ±0.09 +9.6% (noise) 0.043
poi_rescale 0.22 ±0.01 0.24 ±0.01 +9.1% (noise) 0.129
poi_reorient 0.40 ±0.01 0.43 ±0.01 +8.7% (noise) 0.002
poi_to_global 0.21 ±0.01 0.22 ±0.01 +8.5% (noise) 0.005
nii_volumes 0.25 ±0.01 0.27 ±0.01 +8.5% (noise) 0.006
nii_pad_to 0.50 ±0.02 0.54 ±0.02 +8.1% (noise) 0.006
nii_filter_connected_components 0.75 ±0.01 0.81 ±0.04 +7.8% (noise) 0.137
nii_reorient 0.84 ±0.02 0.77 ±0.02 -7.8% (noise) 0.003
poi_resample_from_to 0.74 ±0.01 0.69 ±0.02 -7.2% (noise) 0.004
nii_set_dtype 0.40 ±0.01 0.37 ±0.02 -7.0% (noise) 0.003
nii_center_of_masses 0.18 ±0.00 0.20 ±0.01 +6.6% (noise) 0.011
poi_calc_centroids_nocrop 1.05 ±0.02 1.12 ±0.13 +6.5% (noise) 0.081
nii_get_array 0.02 ±0.00 0.01 ±0.00 -6.2% (noise) 0.073
nii_rescale_seg 0.74 ±0.02 0.70 ±0.01 -5.4% (noise) 0.004
poi_map_labels 0.20 ±0.01 0.19 ±0.01 -4.6% (noise) 0.056
nii_apply_crop 0.67 ±0.04 0.65 ±0.01 -4.0% (noise) 0.313
poi_load 1.00 ±0.02 0.97 ±0.01 -3.8% (noise) 0.001
nii_get_connected_components 0.56 ±0.03 0.58 ±0.01 +3.7% (noise) 0.741
nii_load_seg 1.53 ±0.01 1.57 ±0.02 +2.6% (noise) 0.009
nii_load_img 1.42 ±0.07 1.39 ±0.04 -2.4% (noise) 0.258
nii_save 1.22 ±0.02 1.25 ±0.04 +2.3% (noise) 0.267
poi_save 0.48 ±0.02 0.49 ±0.03 +2.0% (noise) 0.339
nii_compute_crop 0.14 ±0.01 0.14 ±0.00 -1.7% (noise) 0.515
nii_fill_holes 0.78 ±0.01 0.79 ±0.01 +0.9% (noise) 0.144
nii_erode_msk 0.89 ±0.02 0.90 ±0.00 +0.4% (noise) 0.630
poi_local_to_global_arr 0.32 ±0.01 0.32 ±0.01 +0.0% (noise) 0.685

mri_3d — shape (68, 52, 67)

Measurement baseline ms (median ±½·range) head ms (median ±½·range) Δ % p
poi_calc_centroids_nocrop 8.54 ±0.03 8.19 ±0.03 -4.1% 0.000
poi_calc_poi_from_subreg_vert 11.68 ±0.03 12.03 ±0.64 +3.0% 0.142
nii_load_img 8.74 ±0.04 8.59 ±0.04 -1.7% 0.000
nii_save 9.15 ±0.09 9.26 ±0.06 +1.2% 0.017
nii_resample_from_to 39.31 ±0.27 39.05 ±0.29 -0.6% 0.496
… 31 more measurements
Measurement baseline ms (median ±½·range) head ms (median ±½·range) Δ % p
nii_fill_holes 5.28 ±0.02 5.31 ±0.09 +0.5% 0.264
nii_rescale 37.13 ±0.24 37.29 ±0.32 +0.4% 0.423
nii_erode_msk 7.58 ±0.07 7.62 ±0.08 +0.4% 0.715
nii_filter_connected_components 4.56 ±0.03 4.54 ±0.05 -0.3% 0.452
nii_dilate_msk 157.38 ±0.27 157.45 ±0.06 +0.0% 0.527
metric_voxels 236912.00 ±0.00 236912.00 ±0.00 +0.0%
metric_labels 8.00 ±0.00 8.00 ±0.00 +0.0%
metric_foreground_pct 18.21 ±0.00 18.21 ±0.00 +0.0%
poi_to_global 0.24 ±0.01 0.27 ±0.01 +14.0% (noise) 0.001
poi_save 0.50 ±0.02 0.57 ±0.04 +13.5% (noise) 0.025
nii_set_dtype 0.47 ±0.02 0.52 ±0.01 +11.9% (noise) 0.000
nii_extract_label 0.45 ±0.01 0.40 ±0.00 -11.1% (noise) 0.001
nii_get_array 0.05 ±0.00 0.05 ±0.00 +10.3% (noise) 0.001
nii_pad_to 0.71 ±0.02 0.64 ±0.03 -10.1% (noise) 0.001
poi_map_labels 0.22 ±0.01 0.24 ±0.01 +9.9% (noise) 0.009
poi_rescale 0.26 ±0.00 0.28 ±0.00 +8.7% (noise) 0.000
nii_reorient 0.80 ±0.03 0.87 ±0.03 +8.1% (noise) 0.002
poi_resample_from_to 0.72 ±0.02 0.78 ±0.02 +8.0% (noise) 0.000
nii_load_seg 2.85 ±0.05 2.65 ±0.03 -7.0% (noise) 0.000
nii_map_labels 0.98 ±0.01 0.93 ±0.01 -5.1% (noise) 0.000
nii_unique 0.65 ±0.01 0.61 ±0.01 -5.1% (noise) 0.001
nii_apply_crop 0.69 ±0.03 0.65 ±0.02 -5.1% (noise) 0.020
nii_rescale_seg 2.96 ±0.04 3.05 ±0.04 +2.9% (noise) 0.017
poi_load 2.13 ±0.01 2.18 ±0.02 +2.2% (noise) 0.008
nii_compute_crop 0.32 ±0.01 0.32 ±0.01 -2.2% (noise) 0.537
poi_reorient 0.42 ±0.01 0.43 ±0.01 +2.0% (noise) 0.853
nii_volumes 1.94 ±0.01 1.91 ±0.02 -1.6% (noise) 0.009
nii_center_of_masses 1.96 ±0.02 1.94 ±0.02 -1.2% (noise) 0.172
poi_local_to_global_arr 0.33 ±0.01 0.33 ±0.01 +1.0% (noise) 0.573
poi_calc_centroids 2.65 ±0.04 2.68 ±0.01 +0.9% (noise) 0.771
nii_get_connected_components 2.12 ±0.04 2.12 ±0.08 +0.0% (noise) 0.575

mri_2d — shape (68, 52, 1)

Measurement baseline ms (median ±½·range) head ms (median ±½·range) Δ % p
nii_dilate_msk 19.13 ±0.12 18.95 ±0.06 -0.9% 0.048
nii_rescale 5.19 ±0.03 5.23 ±0.02 +0.7% 0.007
nii_resample_from_to 7.40 ±0.11 7.44 ±0.06 +0.6% 0.830
metric_voxels 3536.00 ±0.00 3536.00 ±0.00 +0.0%
metric_labels 7.00 ±0.00 7.00 ±0.00 +0.0%
… 30 more measurements
Measurement baseline ms (median ±½·range) head ms (median ±½·range) Δ % p
metric_foreground_pct 50.17 ±0.00 50.17 ±0.00 +0.0%
poi_save 0.47 ±0.01 0.55 ±0.01 +14.8% (noise) 0.000
poi_to_global 0.24 ±0.01 0.27 ±0.01 +14.4% (noise) 0.001
nii_pad_to 0.48 ±0.01 0.55 ±0.02 +14.2% (noise) 0.001
poi_rescale 0.25 ±0.02 0.28 ±0.01 +12.5% (noise) 0.058
poi_reorient 0.42 ±0.01 0.48 ±0.01 +12.5% (noise) 0.001
nii_apply_crop 0.59 ±0.01 0.66 ±0.02 +11.3% (noise) 0.001
nii_extract_label 0.40 ±0.02 0.36 ±0.01 -11.3% (noise) 0.002
nii_map_labels 0.48 ±0.01 0.43 ±0.01 -10.8% (noise) 0.000
nii_rescale_seg 0.68 ±0.03 0.75 ±0.01 +10.4% (noise) 0.003
nii_compute_crop 0.13 ±0.01 0.14 ±0.01 +8.9% (noise) 0.178
poi_local_to_global_arr 0.31 ±0.00 0.33 ±0.01 +6.7% (noise) 0.000
nii_unique 0.11 ±0.01 0.11 ±0.01 -6.6% (noise) 0.275
nii_reorient 0.77 ±0.03 0.82 ±0.01 +5.6% (noise) 0.004
nii_erode_msk 1.28 ±0.02 1.20 ±0.03 -5.6% (noise) 0.002
nii_fill_holes 1.08 ±0.02 1.02 ±0.03 -5.6% (noise) 0.005
poi_calc_centroids_nocrop 1.34 ±0.01 1.42 ±0.01 +5.5% (noise) 0.000
poi_resample_from_to 0.72 ±0.02 0.76 ±0.02 +5.3% (noise) 0.036
poi_map_labels 0.22 ±0.01 0.23 ±0.01 +5.2% (noise) 0.037
nii_set_dtype 0.36 ±0.02 0.38 ±0.03 +4.8% (noise) 0.237
nii_volumes 0.43 ±0.01 0.41 ±0.02 -4.4% (noise) 0.278
nii_center_of_masses 0.38 ±0.01 0.37 ±0.01 -4.2% (noise) 0.010
nii_get_array 0.01 ±0.00 0.01 ±0.00 -4.0% (noise) 0.901
nii_get_connected_components 0.58 ±0.03 0.57 ±0.02 -2.3% (noise) 0.464
nii_filter_connected_components 0.77 ±0.03 0.78 ±0.02 +1.7% (noise) 0.756
nii_load_img 1.40 ±0.01 1.42 ±0.02 +1.6% (noise) 0.156
nii_load_seg 1.53 ±0.03 1.54 ±0.01 +0.7% (noise) 0.328
nii_save 1.22 ±0.02 1.23 ±0.01 +0.6% (noise) 0.503
poi_calc_centroids 1.05 ±0.01 1.05 ±0.04 -0.5% (noise) 0.603
poi_load 1.89 ±0.01 1.89 ±0.03 +0.0% (noise) 0.829

Gate: a measurement fails when the baseline is ≥ 1 ms, the median grows by ≥ 50%, and Welch's t-test gives p < 0.05. metric_* rows are context only.

Memory (peak RSS growth per call)

baseline e84dbcd vs head e84dbcd · python 3.11.16 · 5 repeats + 1 warmup · sampler proc-status, isolation fork · measurement floor ≈ 0.90 MiB

Showing the 5 most-changed measurements per case; the rest are collapsed. Rows with a baseline below 3 MiB are tagged (noise) — runner jitter on those swamps any real change.

ct_3d — shape (73, 47, 73)

Measurement baseline MiB (median ±½·range) head MiB (median ±½·range) Δ % p
nii_rescale 6.18 ±0.00 6.06 ±0.00 -1.9%
nii_resample_from_to 6.30 ±0.00 6.18 ±0.00 -1.9%
poi_resample_from_to 5.24 ±0.00 5.16 ±0.00 -1.4%
nii_reorient 5.87 ±0.00 5.79 ±0.00 -1.3%
nii_rescale_seg 5.95 ±0.00 5.87 ±0.00 -1.3%
… 31 more measurements
Measurement baseline MiB (median ±½·range) head MiB (median ±½·range) Δ % p
nii_load_seg 5.97 ±0.00 5.90 ±0.00 -1.2%
nii_load_img 3.57 ±0.00 3.53 ±0.00 -1.1%
nii_set_dtype 5.21 ±0.00 5.17 ±0.00 -0.8%
nii_extract_label 5.33 ±0.00 5.29 ±0.00 -0.7%
nii_dilate_msk 5.89 ±0.00 5.85 ±0.00 -0.7%
nii_pad_to 5.39 ±0.00 5.35 ±0.00 -0.7%
nii_map_labels 5.46 ±0.00 5.42 ±0.00 -0.7%
nii_apply_crop 5.83 ±0.00 5.79 ±0.00 -0.7%
nii_fill_holes 6.25 ±0.00 6.21 ±0.00 -0.6%
poi_calc_centroids_nocrop 5.89 ±0.00 5.85 ±0.00 -0.6%
nii_get_connected_components 6.58 ±0.00 6.54 ±0.00 -0.6%
poi_calc_centroids 6.02 ±0.00 5.98 ±0.00 -0.6%
nii_filter_connected_components 6.83 ±0.00 6.79 ±0.00 -0.6%
poi_calc_poi_from_subreg_vert 7.08 ±0.00 7.04 ±0.00 -0.6%
nii_erode_msk 5.89 ±0.00 5.87 ±0.00 -0.5%
nii_center_of_masses 3.28 ±0.00 3.27 ±0.00 -0.1%
nii_volumes 3.53 ±0.00 3.52 ±0.00 -0.1%
nii_save 3.71 ±0.00 3.71 ±0.00 -0.1%
poi_reorient 3.83 ±0.00 3.83 ±0.00 +0.0%
poi_to_global 3.08 ±0.00 3.08 ±0.00 +0.0%
metric_voxels 250463.00 ±0.00 250463.00 ±0.00 +0.0%
metric_labels 3.00 ±0.00 3.00 ±0.00 +0.0%
metric_foreground_pct 14.51 ±0.00 14.51 ±0.00 +0.0%
nii_get_array 1.65 ±0.00 1.65 ±0.00 -0.2% (noise)
nii_compute_crop 2.90 ±0.00 2.90 ±0.00 -0.1% (noise)
nii_unique 2.96 ±0.00 2.96 ±0.00 -0.1% (noise)
poi_rescale 2.61 ±0.00 2.61 ±0.00 +0.0% (noise)
poi_local_to_global_arr 2.96 ±0.00 2.96 ±0.00 +0.0% (noise)
poi_save 1.40 ±0.00 1.40 ±0.00 +0.0% (noise)
poi_map_labels 1.77 ±0.00 1.77 ±0.00 +0.0% (noise)
poi_load 1.61 ±0.00 1.61 ±0.00 +0.0% (noise)

ct_2d — shape (73, 47, 1)

Measurement baseline MiB (median ±½·range) head MiB (median ±½·range) Δ % p
nii_rescale 6.11 ±0.00 6.00 ±0.00 -1.9%
nii_resample_from_to 6.23 ±0.00 6.12 ±0.00 -1.8%
poi_resample_from_to 5.18 ±0.00 5.10 ±0.00 -1.4%
nii_reorient 5.80 ±0.00 5.73 ±0.00 -1.3%
nii_rescale_seg 5.88 ±0.00 5.81 ±0.00 -1.3%
… 30 more measurements
Measurement baseline MiB (median ±½·range) head MiB (median ±½·range) Δ % p
nii_load_seg 5.91 ±0.00 5.84 ±0.00 -1.2%
nii_load_img 3.50 ±0.00 3.46 ±0.00 -1.0%
nii_set_dtype 5.14 ±0.00 5.11 ±0.00 -0.7%
nii_dilate_msk 5.83 ±0.00 5.79 ±0.00 -0.7%
nii_extract_label 5.27 ±0.00 5.23 ±0.00 -0.7%
nii_pad_to 5.32 ±0.00 5.29 ±0.00 -0.7%
nii_map_labels 5.39 ±0.00 5.36 ±0.00 -0.7%
nii_apply_crop 5.77 ±0.00 5.73 ±0.00 -0.6%
poi_calc_centroids_nocrop 5.89 ±0.00 5.85 ±0.00 -0.6%
nii_fill_holes 6.18 ±0.00 6.14 ±0.00 -0.6%
nii_get_connected_components 6.52 ±0.00 6.48 ±0.00 -0.5%
poi_calc_centroids 5.95 ±0.00 5.92 ±0.00 -0.5% 0.000
nii_filter_connected_components 6.77 ±0.00 6.73 ±0.00 -0.5%
nii_erode_msk 5.83 ±0.00 5.80 ±0.00 -0.4%
nii_save 3.65 ±0.00 3.65 ±0.00 +0.0%
nii_volumes 3.46 ±0.00 3.46 ±0.00 +0.0%
nii_center_of_masses 3.21 ±0.00 3.21 ±0.00 +0.0%
poi_reorient 3.77 ±0.00 3.77 ±0.00 +0.0%
poi_to_global 3.02 ±0.00 3.02 ±0.00 +0.0%
metric_voxels 3431.00 ±0.00 3431.00 ±0.00 +0.0%
metric_labels 3.00 ±0.00 3.00 ±0.00 +0.0%
metric_foreground_pct 37.60 ±0.00 37.60 ±0.00 +0.0%
nii_get_array 1.59 ±0.00 1.59 ±0.00 +0.0% (noise)
nii_compute_crop 2.84 ±0.00 2.84 ±0.00 +0.0% (noise)
nii_unique 2.90 ±0.00 2.90 ±0.00 +0.0% (noise)
poi_rescale 2.54 ±0.00 2.54 ±0.00 +0.0% (noise)
poi_local_to_global_arr 2.89 ±0.00 2.89 ±0.00 +0.0% (noise)
poi_save 1.34 ±0.00 1.34 ±0.00 +0.0% (noise)
poi_map_labels 1.71 ±0.00 1.71 ±0.00 +0.0% (noise)
poi_load 1.55 ±0.00 1.55 ±0.00 +0.0% (noise)

mri_3d — shape (68, 52, 67)

Measurement baseline MiB (median ±½·range) head MiB (median ±½·range) Δ % p
nii_rescale 6.11 ±0.00 6.00 ±0.00 -1.9%
nii_resample_from_to 6.23 ±0.00 6.12 ±0.00 -1.8%
poi_resample_from_to 5.18 ±0.00 5.10 ±0.00 -1.4%
nii_reorient 5.80 ±0.00 5.73 ±0.00 -1.3%
nii_rescale_seg 5.88 ±0.00 5.81 ±0.00 -1.3%
… 31 more measurements
Measurement baseline MiB (median ±½·range) head MiB (median ±½·range) Δ % p
nii_load_seg 5.91 ±0.00 5.84 ±0.00 -1.2%
nii_load_img 3.56 ±0.00 3.53 ±0.00 -1.0%
nii_set_dtype 5.20 ±0.00 5.17 ±0.00 -0.7%
nii_dilate_msk 5.83 ±0.00 5.79 ±0.00 -0.7%
nii_extract_label 5.27 ±0.00 5.23 ±0.00 -0.7%
nii_pad_to 5.32 ±0.00 5.29 ±0.00 -0.7%
nii_map_labels 5.39 ±0.00 5.36 ±0.00 -0.7%
nii_apply_crop 5.77 ±0.00 5.73 ±0.00 -0.6%
poi_calc_centroids_nocrop 5.82 ±0.00 5.79 ±0.00 -0.6%
poi_calc_centroids 5.95 ±0.00 5.92 ±0.00 -0.6%
nii_fill_holes 6.18 ±0.00 6.14 ±0.00 -0.6%
nii_get_connected_components 6.52 ±0.00 6.48 ±0.00 -0.5%
nii_filter_connected_components 6.77 ±0.00 6.73 ±0.00 -0.5%
poi_calc_poi_from_subreg_vert 7.07 ±0.00 7.04 ±0.00 -0.5%
nii_erode_msk 5.83 ±0.00 5.80 ±0.00 -0.4%
nii_save 3.65 ±0.00 3.65 ±0.00 +0.0%
nii_volumes 3.46 ±0.00 3.46 ±0.00 +0.0%
nii_center_of_masses 3.21 ±0.00 3.21 ±0.00 +0.0%
poi_reorient 3.77 ±0.00 3.77 ±0.00 +0.0%
poi_to_global 3.02 ±0.00 3.02 ±0.00 +0.0%
metric_voxels 236912.00 ±0.00 236912.00 ±0.00 +0.0%
metric_labels 8.00 ±0.00 8.00 ±0.00 +0.0%
metric_foreground_pct 18.21 ±0.00 18.21 ±0.00 +0.0%
nii_get_array 1.59 ±0.00 1.59 ±0.00 +0.0% (noise)
nii_compute_crop 2.84 ±0.00 2.84 ±0.00 +0.0% (noise)
nii_unique 2.90 ±0.00 2.90 ±0.00 +0.0% (noise)
poi_rescale 2.54 ±0.00 2.54 ±0.00 +0.0% (noise)
poi_local_to_global_arr 2.89 ±0.00 2.89 ±0.00 +0.0% (noise)
poi_save 1.40 ±0.00 1.40 ±0.00 +0.0% (noise)
poi_map_labels 1.71 ±0.00 1.71 ±0.00 +0.0% (noise)
poi_load 1.55 ±0.00 1.55 ±0.00 +0.0% (noise)

mri_2d — shape (68, 52, 1)

Measurement baseline MiB (median ±½·range) head MiB (median ±½·range) Δ % p
nii_rescale 6.11 ±0.00 6.00 ±0.00 -1.9%
nii_resample_from_to 6.23 ±0.00 6.12 ±0.00 -1.8%
poi_resample_from_to 5.18 ±0.00 5.10 ±0.00 -1.4%
nii_reorient 5.80 ±0.00 5.73 ±0.00 -1.3%
nii_rescale_seg 5.88 ±0.00 5.81 ±0.00 -1.3%
… 30 more measurements
Measurement baseline MiB (median ±½·range) head MiB (median ±½·range) Δ % p
nii_load_seg 5.91 ±0.00 5.84 ±0.00 -1.2%
nii_load_img 3.56 ±0.00 3.53 ±0.00 -1.0%
nii_set_dtype 5.20 ±0.00 5.17 ±0.00 -0.7%
nii_dilate_msk 5.83 ±0.00 5.79 ±0.00 -0.7%
nii_extract_label 5.27 ±0.00 5.23 ±0.00 -0.7%
nii_pad_to 5.32 ±0.00 5.29 ±0.00 -0.7%
nii_map_labels 5.39 ±0.00 5.36 ±0.00 -0.7%
nii_apply_crop 5.77 ±0.00 5.73 ±0.00 -0.6%
poi_calc_centroids_nocrop 5.89 ±0.00 5.85 ±0.00 -0.6%
poi_calc_centroids 5.95 ±0.00 5.92 ±0.00 -0.6%
nii_fill_holes 6.18 ±0.00 6.14 ±0.00 -0.6%
nii_get_connected_components 6.52 ±0.00 6.48 ±0.00 -0.5%
nii_filter_connected_components 6.77 ±0.00 6.73 ±0.00 -0.5%
nii_erode_msk 5.83 ±0.00 5.80 ±0.00 -0.4%
nii_save 3.65 ±0.00 3.65 ±0.00 +0.0%
nii_volumes 3.46 ±0.00 3.46 ±0.00 +0.0%
nii_center_of_masses 3.21 ±0.00 3.21 ±0.00 +0.0%
poi_reorient 3.77 ±0.00 3.77 ±0.00 +0.0%
poi_to_global 3.02 ±0.00 3.02 ±0.00 +0.0%
metric_voxels 3536.00 ±0.00 3536.00 ±0.00 +0.0%
metric_labels 7.00 ±0.00 7.00 ±0.00 +0.0%
metric_foreground_pct 50.17 ±0.00 50.17 ±0.00 +0.0%
nii_get_array 1.59 ±0.00 1.59 ±0.00 +0.0% (noise)
nii_compute_crop 2.84 ±0.00 2.84 ±0.00 +0.0% (noise)
nii_unique 2.90 ±0.00 2.90 ±0.00 +0.0% (noise)
poi_rescale 2.54 ±0.00 2.54 ±0.00 +0.0% (noise)
poi_local_to_global_arr 2.89 ±0.00 2.89 ±0.00 +0.0% (noise)
poi_save 1.40 ±0.00 1.40 ±0.00 +0.0% (noise)
poi_map_labels 1.71 ±0.00 1.71 ±0.00 +0.0% (noise)
poi_load 1.55 ±0.00 1.55 ±0.00 +0.0% (noise)

Gate: a measurement fails when the baseline is ≥ 1 MiB, the median grows by ≥ 50%, and Welch's t-test gives p < 0.05. metric_* rows are context only.

@Hendrik-code Hendrik-code self-assigned this Aug 28, 2026
@Hendrik-code Hendrik-code added the enhancement New feature or request label Aug 28, 2026
@Hendrik-code
Hendrik-code merged commit 42879c7 into main Aug 28, 2026
6 checks passed
@Hendrik-code
Hendrik-code deleted the feat/nii-bbox-chain-filter branch August 28, 2026 11:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants