Improve pairwise registration: multi-scale ITK, shift filtering, motor-position mode#86
Conversation
Closes #79. Adds robust multi-scale 2D ITK registration functions (register_2d_images_sitk, apply_transform, find_best_z) to stitching/registration.py. Introduces utils/shifts.py for XY shift management (load/filter/interpolate) and utils/metrics.py for pipeline metrics collection. Replaces linum_estimate_transform_pairwise.py with improved linum_register_pairwise.py and extends linum_estimate_transform.py with motor-position mode, IQR outlier filtering, and fallback transforms.
There was a problem hiding this comment.
is it like before, i.e. fixed and moving volumes are expected to already be roughly aligned and with lateral dimensions?
There was a problem hiding this comment.
Yes! This script is executed after all slices are brought to the common space.
| p.add_argument("--use_motor_positions", action="store_true", | ||
| help="Use motor positions (expected tile spacing) instead of image registration.\n" | ||
| "This creates a transform based purely on the overlap fraction,\n" | ||
| "corresponding to the precise motor/stage positions from acquisition.\n" | ||
| "Recommended when motor positions are reliable.") |
There was a problem hiding this comment.
I actually use this most of the time these days. I found that using the motor positions and using a heavily restricted registration afterwards to refine was more reliable.
| @@ -0,0 +1,386 @@ | |||
| # -*- coding: utf-8 -*- | |||
| """ | |||
| XY shift utilities for serial-section alignment. | |||
There was a problem hiding this comment.
Everything can be a utility so I'd suggest having this file under linumpy/shifts/utils.py instead of linumpy/utils/shifts.py
There was a problem hiding this comment.
Yeah, fair enough. The distinction is not really useful to make.
There was a problem hiding this comment.
I moved that and some other code around based on their functionality.
…er and main function
…tinguish genuine re-homing events from encoder glitch spikes, improving robustness of shift correction.
…and align_images_sitk functions for cleaner implementation.
- Moved `data_io` from `linumpy.utils` to `linumpy.io`. - Introduced `mosaic_grid.py` in `linumpy.stitching` for managing mosaic grid images. - Updated imports in various scripts and test files to reflect the new module structure. - Removed unused imports from `linumpy.utils.__init__.py`. - Adjusted references to `MosaicGrid` and related functions in scripts for illumination compensation, cropping, and stitching. - Ensured consistency in the import paths across the codebase.
… script to handle mosaic grid expansion artifacts
…act step handling, adding unreliable transition refinement via image registration, and improving inter-slice shift estimation from tile stage positions.
Summary
Closes #79
Addresses issue #79 by substantially improving the robustness of pairwise slice registration.
Key Changes
linumpy/stitching/registration.py— new functions:register_2d_images_sitk: multi-scale 2D ITK registration (Euler/affine/translation) with mask support and optional 3D transform outputapply_transform: resample a moving image with a SimpleITK transformfind_best_z: cross-correlation search for best matching Z-index across slicesregister_refinement: gradient-descent rotation + translation refinementcreate_transform: builds a 3D Euler transform from 2D parametersNew
linumpy/utils/shifts.py— XY shift utilities:load_shifts_csv,compute_cumulative_shifts,filter_outlier_shifts(IQR-based),interpolate_missing_shiftsNew
linumpy/utils/metrics.py— pipeline metrics collection for registration, mosaic, and stacking stepsNew
scripts/linum_register_pairwise.py— simplified pairwise registration CLI based on motor positions; outputstransform.tfm,offsets.txt,metrics.jsonscripts/linum_estimate_transform.py— gains:--use_motor_positionsflagDeleted
scripts/linum_estimate_transform_pairwise.pyand its test (replaced by the new scripts above)New
linumpy/tests/test_utils_shifts.pyDependencies
Depends on PR #85 (thread config module).