Skip to content

Function to rescale an affine matrix #670

Closed
@effigies

Description

@effigies

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions