Closed
Description
Given that image.header.set_zooms()
does not update an affine, a useful tool would be a function that takes a given affine matrix and returns an updated matrix that encodes the desired zooms.
Adapting from @ellisdg's suggestions:
def rescale_affine(affine, target_zooms):
ret = np.array(affine, copy=True)
RZS = affine[:3, :3]
zooms = np.sqrt(np.sum(RZS ** 2, axis=0))
scale = np.divide(target_zooms, zooms)
ret[:3, :3] = RZS * np.diag(scale)
return ret
The correct way to fix the zooms on a file would then be:
import nibabel as nb
orig = nb.load(fname)
img = orig.__class__(np.array(orig.dataobj),
rescale_affine(orig.affine, target_zooms),
orig.header)
img.to_filename(fname)
This approach would leave the RAS coordinates of (i, j, k) = (0, 0, 0)
the same. It may be desirable instead to adjust the translation so that the IJK coordinates of the RAS origin are constant. Possibly controlled by a parameter.
I'm not absolutely positive that this handles shear components correctly. I'd need to check.
Sub-issue identified in #619.