Affine transformation and resampling data

Dear experts:

I have a very basic question about affine transformation and nibabel. It seems to me that you do not need to resample data when applying an affine transformation to a dataset (of course you can but you do not need to if you want to preserve the original resolution). This problem occurs when aligning epi to anat. Typically epi data have a lower resolution and I do not want to upsample epi data to match anat data.

The most straightfoward thing to do is as follows:

# give we have an affine transformation <affine>
import nibabel as nib
moving = nib.load('epi.nii.gz') # load
moving_vox2mm = moving.affine
new_vox2mm = affine.dot(moving_vox2mm)  # apply affine transform here
nib.save(moving.__class__(moving.get_data(), new_vox2mm, moving.header), 'epi_al2anat.nii.gz')

In this regime, it seems you do not need to even touch the data at all. But almost all software ask you to specify a base grid to resample the data. Did I miss something here?

Thanks.

Cheers
Ruyuan

@ruyuanzhang, using a visualization tool that correctly implements s/q-form matrices, the code you’ve written should lead to correctly render epi_al2anat.nii.gz overlaid on top of the anatomical image (which means the visualization software is correctly resampling the data using the affine).

That is assuming the affine variable in your snippet is an affine matrix that maps coordinates in EPI space into anatomical space. This is the core of the question, because if you run some registration software and used the anatomical as reference, the affine matrix will map coordinates from anatomical to EPI (ie. you’ll need to invert such an affine).

Data are not touched and that is actually the rationale to include those x-forms in the NIfTI format: to avoid resamplings that make use of interpolation to calculate off-grid values (and modifying the original data).

If you want to regrid your data, then your problem is very similar to this other one Nibabel - How can we rescale a 3d image. In your case the target affine is given by the gridding you create in anatomical space.