Skip to content

Commit ac80266

Browse files
committed
fix: address offset with factors
1 parent fb142d5 commit ac80266

File tree

2 files changed

+31
-19
lines changed

2 files changed

+31
-19
lines changed

sdcflows/utils/tests/test_tools.py

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -36,31 +36,45 @@ def test_epi_mask(tmpdir, testdata_dir):
3636

3737

3838
@pytest.mark.parametrize("padding", [0, 1, 4])
39-
@pytest.mark.parametrize("factor", [1, 4, 0.5])
40-
def test_deoblique_and_zooms(padding, factor):
39+
@pytest.mark.parametrize("factor", [1, 4, 0.8])
40+
@pytest.mark.parametrize("centered", [True, False])
41+
@pytest.mark.parametrize("rotate", [
42+
np.eye(4),
43+
# Rotate 90 degrees around x-axis
44+
np.array([[0, 1, 0, 0], [0, 0, 1, 0], [1, 0, 0, 0], [0, 0, 0, 1]]),
45+
])
46+
def test_deoblique_and_zooms(tmpdir, padding, factor, centered, rotate):
4147
"""Check deoblique and denser."""
48+
tmpdir.chdir()
4249

4350
# Generate an example reference image
44-
ref_data = np.zeros((20, 30, 40), dtype=np.float32)
45-
ref_affine = np.diag([1.0, 1.2, 0.8, 1.0])
51+
ref_data = np.zeros((20, 32, 40), dtype=np.float32)
52+
ref_data[1:-2, 10:-11, 1:-2] = 1
53+
ref_affine = np.diag([2.0, 1.25, 1.0, 1.0])
54+
ref_zooms = nb.affines.voxel_sizes(ref_affine)
55+
if centered:
56+
ref_affine[:3, 3] -= nb.affines.apply_affine(
57+
ref_affine, 0.5 * (np.array(ref_data.shape) - 1),
58+
)
4659
ref_img = nb.Nifti1Image(ref_data, ref_affine)
47-
ref_zooms = np.array(ref_img.header.get_zooms()[:3])
4860

4961
# Generate an example oblique image
50-
ob_data = np.ones_like(ref_data)
51-
52-
# Rotate 90 degrees around x-axis
53-
rotate = np.array([[0, 1, 0, 0], [0, 0, 1, 0], [1, 0, 0, 0], [0, 0, 0, 1]])
54-
ob_img = nb.Nifti1Image(ob_data, rotate @ ref_affine)
62+
ob_img = nb.Nifti1Image(ref_data, rotate @ ref_affine)
5563

5664
# Call function with default parameters
5765
out_img = deoblique_and_zooms(ref_img, ob_img, padding=padding, factor=factor)
5866

5967
# Check output shape and zooms
6068
assert np.allclose(out_img.header.get_zooms()[:3], ref_zooms / factor)
6169

70+
ref_resampled = Affine(reference=out_img).apply(ref_img, order=0)
6271
resampled = Affine(reference=out_img).apply(ob_img, order=0)
63-
ref_volume = ref_data.size * ref_zooms.prod()
72+
ref_img.to_filename("reference.nii.gz")
73+
ob_img.to_filename("moving.nii.gz")
74+
ref_resampled.to_filename("ref_resampled.nii.gz")
75+
resampled.to_filename("resampled.nii.gz")
76+
# import pdb; pdb.set_trace()
77+
ref_volume = ref_data.sum() * ref_zooms.prod()
6478
res_volume = resampled.get_fdata().sum() * np.prod(resampled.header.get_zooms())
6579
# 20% of change in volume is too high, must be an error somewhere
6680
assert abs(ref_volume - res_volume) < ref_volume * 0.2

sdcflows/utils/tools.py

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,12 @@ def deoblique_and_zooms(in_reference, oblique, factor=4, padding=1):
4343
"""
4444
from itertools import product
4545
import numpy as np
46-
from nibabel.affines import apply_affine, rescale_affine
46+
from nibabel.affines import apply_affine
4747

4848
# Reference space metadata
4949
hdr = in_reference.header.copy()
5050
affine = in_reference.affine
5151
ref_shape = np.array(in_reference.shape[:3])
52-
ref_zooms = np.array(hdr.get_zooms()[:3])
5352
_, scode = in_reference.get_sform(coded=True)
5453
_, qcode = in_reference.get_qform(coded=True)
5554

@@ -60,9 +59,6 @@ def deoblique_and_zooms(in_reference, oblique, factor=4, padding=1):
6059
)
6160
extent_ijk = apply_affine(np.linalg.inv(affine), extent)
6261

63-
if isinstance(padding, int):
64-
padding = tuple([padding] * 3)
65-
6662
underflow = np.clip(extent_ijk.min(0) - padding, None, 0).astype(int)
6763
overflow = np.ceil(np.clip(extent_ijk.max(0) + padding + 1 - ref_shape, 0, None)).astype(int)
6864
if np.any(underflow < 0) or np.any(overflow > 0):
@@ -73,9 +69,11 @@ def deoblique_and_zooms(in_reference, oblique, factor=4, padding=1):
7369

7470
# Make grid denser
7571
if abs(1.0 - factor) > 1e-5:
76-
new_shape = np.rint(ref_shape * factor)
77-
affine = rescale_affine(affine, ref_shape, ref_zooms / factor, new_shape)
78-
ref_shape = new_shape
72+
cur_center = apply_affine(affine, 0.5 * (ref_shape - 1))
73+
affine[:3, :3] /= factor
74+
ref_shape = np.rint(ref_shape * factor)
75+
new_center = affine[:3, :3] @ (0.5 * (ref_shape - 1))
76+
affine[:3, 3] = cur_center - new_center
7977

8078
# Generate new reference
8179
hdr.set_sform(affine, scode)

0 commit comments

Comments
 (0)