2121# https://www.nipreps.org/community/licensing/
2222#
2323"""Image processing tools."""
24+ import nibabel as nb
2425
2526
26- def deoblique_and_zooms (in_reference , oblique , factor = 4 , padding = 1 ):
27+ def deoblique_and_zooms (
28+ in_reference : nb .spatialimages .SpatialImage ,
29+ oblique : nb .spatialimages .SpatialImage ,
30+ factor : int = 4 ,
31+ padding : int = 1 ,
32+ factor_tol : float = 1e-4 ,
33+ ):
2734 """
2835 Generate a sampling reference aligned with in_reference fully covering oblique.
2936
@@ -39,6 +46,8 @@ def deoblique_and_zooms(in_reference, oblique, factor=4, padding=1):
3946 padding : :obj:`int`
4047 Number of additional voxels around the most extreme positions of the projection of
4148 oblique on to the reference.
49+ factor_tol : :obj:`float`
50+ Absolute tolerance to determine whether factor is one.
4251
4352 """
4453 from itertools import product
@@ -54,24 +63,23 @@ def deoblique_and_zooms(in_reference, oblique, factor=4, padding=1):
5463 _ , qcode = in_reference .get_qform (coded = True )
5564
5665 # Calculate the 8 most extreme coordinates of oblique in in_reference space
57- extent = apply_affine (
58- oblique .affine ,
59- np .array (list (product ((0 , 1 ), repeat = 3 ))) * (np .array (oblique .shape [:3 ]) - 1 ),
66+ corners = np .array (list (product ((0 , 1 ), repeat = 3 ))) * (
67+ np .array (oblique .shape [:3 ]) - 1
6068 )
61- extent_ijk = apply_affine (np .linalg .inv (affine ), extent )
69+ extent_ijk = apply_affine (np .linalg .inv (affine ) @ oblique . affine , corners )
6270
6371 underflow = np .clip (extent_ijk .min (0 ) - padding , None , 0 ).astype (int )
6472 overflow = np .ceil (
6573 np .clip (extent_ijk .max (0 ) + padding + 1 - ref_shape , 0 , None )
6674 ).astype (int )
6775 if np .any (underflow < 0 ) or np .any (overflow > 0 ):
6876 # Add under/overflow voxels
69- ref_shape += np . abs ( underflow ) + overflow
77+ ref_shape += overflow - underflow
7078 # Consistently update origin
7179 affine [:- 1 , - 1 ] = apply_affine (affine , underflow )
7280
7381 # Make grid denser
74- if abs (1.0 - factor ) > 1e-4 :
82+ if abs (1.0 - factor ) > factor_tol :
7583 new_shape = np .rint (ref_shape * factor )
7684 affine = rescale_affine (affine , ref_shape , ref_zooms / factor , new_shape )
7785 ref_shape = new_shape
@@ -81,7 +89,7 @@ def deoblique_and_zooms(in_reference, oblique, factor=4, padding=1):
8189 hdr .set_qform (affine , qcode )
8290
8391 return in_reference .__class__ (
84- np . zeros (ref_shape .astype (int ), dtype = hdr . get_data_dtype ( )),
92+ nb . fileslice . strided_scalar (ref_shape .astype (int )),
8593 affine ,
8694 hdr ,
8795 )
0 commit comments