Repository navigation
Affine Transform does not return target affine #7092
Description
Activity
the Affine transform assumes that the origin is at the image spatial center when applying
resample_affine:MONAI/monai/transforms/spatial/array.py
Line 2285 in 100db27
mat = shift_1 @ convert_data_type(mat, np.ndarray)[0] @ shift_2 the Affine transform assumes that the origin is at the image spatial center when applying
resample_affine:MONAI/monai/transforms/spatial/array.py
Line 2285 in 100db27
mat = shift_1 @ convert_data_type(mat, np.ndarray)[0] @ shift_2 Good that you are pointing this out. I was already working on a second bug report with respect to the offset that output images have.
If I do something like this:
offset = create_translate(len(image_shape), [float(d - 1) / 2 for d in image_shape]) resample_affine = np.linalg.inv(offset) @ resample_affine @ offset
then it works and the output is correct, but it's also rather unexpected that this is necessary.
Note thatcompute_w_affineshifts in the opposite direction, which results in broken images. Following the code ofaffine_funclooks to me as if that is not actually used as output affine (at least I can not see where within the code).I'm also confused on when the
normalizedparameter is necessary then. I thought something like that is the use-case for that parameter? As if I my self have to shift to a center, I'm doing the normalization, which I expected Affine to do.normalized: indicating whether the provided
affineis defined to include a normalization
transform converting the coordinates from[-(size-1)/2, (size-1)/2](defined increate_grid) to
[0, size - 1]or[-1, 1]in order to be compatible with the underlying resampling API.
Ifnormalized=False, additional coordinate normalization will be applied before resampling.
See also: :py:func:monai.networks.utils.normalize_transform.So in case of
normalized=FalseI understood this to not have this center origin requirement.Also why is this necessary at all or rather if the computation requires that center origin, why doesn't the Affine transform perform that shift?
The documentation on these functions and parameters could be improved. If there is a center origin requirement, it would be good if the Affine transform doc string would note that and potentially even give instruction on how to center it if not already done. As said, I'm not able to understand what the
normalizedparameter is for then. Thecompute_w_affinefunction has no doc string explaining what it is useful for.I don't know if it's just the data we are working with (MRI images) but we already spend many hours struggling with unexpected behavior of functions in this area. Maybe it's because all libraries seem to impose different conventions. ITK is especially terrible and we try to avoid it in our code base where ever we can.
Maybe it's just a learning on our side, or we can make some useful improvements out of this, what do you thing?
thanks, agree that the documentation could be largely improved..
- addeddocumentationImprovements or additions to documentationImprovements or additions to documentationenhancementNew feature or requestNew feature or request
on Oct 6, 2023 I would gladly contribute, but I first need to solve my confusion expressed above. Let me know if and when I can help (would also be available for a call if that's useful).
- added a commit that references this issue
on Jan 31, 2026 - added 3 commits that reference this issue
on Feb 23, 2026 - added a commit that references this issue
on Jun 24, 2026
Describe the bug
The output image of the Affine transform does not have the correct affine.
To Reproduce
image.nii.gz
labels.nii.gz
target_affine
source_affine @ resample_affine
resampled_mt.affine.numpy()
diff
As we can see,
source_affine @ resample_affineis equal totarget_affine.But
resampled_mt.affine.numpy()is different and there is adiff.Expected behavior
I expected
resampled_mt.affine.numpy()to be equal tosource_affine @ resample_affine(ortarget_affine).Environment