Add slice interpolation for missing and degraded tissue sections#87
Add slice interpolation for missing and degraded tissue sections#87FIrgolitsch wants to merge 3 commits intomainfrom
Conversation
New linumpy/stitching/interpolation.py library with three interpolation methods (average, weighted-Gaussian, registration-based morphing) and degraded-slice quality assessment using SSIM, edge score, and variance. Corresponding linum_interpolate_missing_slice.py CLI and unit tests.
…treamline min-max scaling for fixed and moving images.
CHrlS98
left a comment
There was a problem hiding this comment.
I have a few questions on how it works. see comments below. Also a few changes requested.
| @@ -0,0 +1,288 @@ | |||
| # -*- coding: utf-8 -*- | |||
| """ | |||
| Slice interpolation utilities for missing or degraded serial sections. | |||
There was a problem hiding this comment.
Unclear to me what a "slice" actually is... Is it a whole 3D volume, like a slab, or a 2D slice taken from a 3D volume?
| """Simple 50/50 average of two adjacent volumes. | ||
|
|
||
| Parameters | ||
| ---------- | ||
| vol_before : np.ndarray | ||
| Volume before missing slice (Z, X, Y). | ||
| vol_after : np.ndarray | ||
| Volume after missing slice (Z, X, Y). |
There was a problem hiding this comment.
what are the expected shape of these volumes? do they correspond to slabs, tiles, slices?
There was a problem hiding this comment.
Also this method (and others in this file, Iguess) expect that both volumes were registered beforehand right? and that slices at z=zi in both volumes describe the same structures? This would need to be mentioned somewhere.
linumpy/stitching/interpolation.py
Outdated
| np.ndarray | ||
| Weighted average. | ||
| """ | ||
| from scipy.ndimage import gaussian_filter |
There was a problem hiding this comment.
move import to top of file?
linumpy/stitching/interpolation.py
Outdated
| import SimpleITK as sitk | ||
| from linumpy.stitching.registration import register_2d_images_sitk, apply_transform |
There was a problem hiding this comment.
move imports to top of file
linumpy/stitching/interpolation.py
Outdated
| metrics : dict | ||
| Individual metric scores. | ||
| """ | ||
| from linumpy.utils.image_quality import ( |
| def blend_with_degraded(interpolated: np.ndarray, | ||
| degraded: np.ndarray, | ||
| quality_weight: float) -> np.ndarray: | ||
| """Blend an interpolated result with a degraded slice weighted by quality. |
There was a problem hiding this comment.
add a note on what that could be used for. Quality control?
| This script implements registration-based morphing interpolation to reconstruct | ||
| a missing slice in a serial sectioning dataset. The method: | ||
|
|
||
| 1. Registers the slice before the gap to the slice after |
There was a problem hiding this comment.
a slice is a 3D volume? Is it 2D registration? If so it means it assumes that the same content is found at depth z_i in both volumes? I don't understand where it goes in the reconstruction pipeline.
| def register_slices_2d(fixed_slice, moving_slice, metric='MSE', max_iterations=1000): | ||
| """ |
linumpy/stitching/interpolation.py
Outdated
| sitk.AffineTransform | ||
| Transform representing half the transformation. | ||
| """ | ||
| import SimpleITK as sitk |
CHrlS98
left a comment
There was a problem hiding this comment.
Two additional comments on your latest changes. Some comments from previous review are not resolved yet. Take your time, I just want to make sure I'm not too much of a bottleneck.
| Z-index for registration reference. Default: middle Z. | ||
| When provided, overrides automatic plane selection and uses this | ||
| z-index (clamped to each volume's bounds) as the registration | ||
| reference in both volumes. When *None* (default), |
There was a problem hiding this comment.
shoudn't this be a tuple mapping a slice from fixed volume to corresponding slice in moving volume? using the same reference slice in both volumes never makes sense does it?
| help="Z-index (in each volume, clamped to that volume's bounds)\n" | ||
| "to use as the registration reference plane.\n" | ||
| "If not specified, the best-correlated plane pair within\n" | ||
| "--overlap_search_window planes from each boundary is used\n" | ||
| "automatically (recommended).") |
Summary
Serial section imaging frequently produces missing or severely degraded slices (due to tissue loss, fold artefacts, etc.). This PR provides a library and CLI to synthetically reconstruct such sections from adjacent good slices.
Key Changes
New
linumpy/stitching/interpolation.py:interpolate_average: simple mean of adjacent slicesinterpolate_weighted: Gaussian-weighted blendinterpolate_registration_based: morphing via SimpleITK with linear/Gaussian blendassess_degraded_slice_quality: SSIM + edge score + varianceblend_with_degraded: quality-weighted blend of interpolated and original sliceNew
scripts/linum_interpolate_missing_slice.py— full CLI; supports--method {average,weighted,registration}and--degraded_slicefor quality-blended output when a poor slice exists rather than no sliceNew tests:
linumpy/tests/test_stitching_interpolation.pyscripts/tests/test_interpolate_missing_slice.pyDependencies
Depends on PR #85 (thread config module).