Skip to content

Resampling of images with different dimensions needs thought #411

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
matthew-brett opened this issue Feb 25, 2016 · 1 comment
Open

Resampling of images with different dimensions needs thought #411

matthew-brett opened this issue Feb 25, 2016 · 1 comment

Comments

@matthew-brett
Copy link
Member

Currently (after merge of #255):

In [1]: from os.path import dirname, join
In [2]: import nibabel as nib
In [4]: data_dir = join(dirname(nib.__file__), 'tests', 'data')
In [6]: anat = nib.load(join(data_dir, 'anatomical.nii'))
In [7]: anat.shape
Out[7]: (33, 41, 25)

In [8]: func = nib.load(join(data_dir, 'functional.nii'))
In [9]: func.shape
Out[9]: (17, 21, 3, 20)

In [10]: from nibabel.processing import resample_from_to
In [11]: resample_from_to(func, anat)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-11-0be28b6142bd> in <module>()
----> 1 resample_from_to(func, anat)

/Users/mb312/dev_trees/nibabel/nibabel/processing.py in resample_from_to(from_img, to_vox_map, order, mode, cval, out_class)
    165         raise AffineError('from_img must be at least 3D')
    166     a_from_affine = adapt_affine(from_img.affine, from_n_dim)
--> 167     to_vox2from_vox = npl.inv(a_from_affine).dot(a_to_affine)
    168     rzs, trans = to_matvec(to_vox2from_vox)
    169     data = spnd.affine_transform(from_img.dataobj,

ValueError: shapes (5,5) and (4,4) not aligned: 5 (dim 1) != 4 (dim 0)

It's quite common to resample a functional 4D series to the space defined by another image.

I guess we could support this by specifically allowing the from image to have more dimensions than the to image, or be less general, and special-case the from 4D, to 3D case.

Any thoughts?

@servoz
Copy link

servoz commented Apr 6, 2020

Hi,
I'm just about to working on a possibility (as general as possible) to resample images in our project.

If we need to resample a 3D from a 4D we can consider to do something like:

>>> import nibabel as nib 
>>> import nibabel.processing as nibp
>>> img3D=nib.load('pathTo3Dimg.nii')
>>> img4D=nib.load('pathTo4Dimg.nii')
>>> img3D.shape
(512, 512, 160)
>>> img4D.shape
(96, 96, 53, 240)
>>> img3DFrom4D=img4D.slicer[:,:,:,0]
>>> img3DFrom4D.shape # line 8
(96, 96, 53)
>>> img3Dresampled=nibp.resample_from_to(img3D, img3DFrom4D, order=3)
>>> img3Dresampled.shape
(96, 96, 53)
>>> nib.save(img3Dresampled, 'pathTo3DresampledImg.nii')

However, as you indicate in this ticket, things get more complicated if we want to do the opposite, because resample_from_to() function seems to accept only matrices of same dimensions !
While waiting for you to integrate this possibility into the resample_from_to() function (but given the opening date of this ticket, I doubt it's one of your priorities), do you have a workaround ?

For example we could consider doing something like this (from line 8, above):

>>> img3DFrom4Dresampled=nibp.resample_from_to(img3DFrom4D, img3D, order=3)
>>> img3DFrom4Dresampled.shape
(512, 512, 160)

So from now on "it would be enough" to reconstruct (including header, etc ...) the 4D image by including the resampled spacial cube (img3DFrom4Dresampled) and the 4th dimension which is not spacial in the case of a functional 4D.

I confess I don't know nibabel very well yet and I don't really know how I could do it with nibabel, and if it's possible ? ...

If we manage to do this, it will be possible to resample a 3D image from another 3D image (it already works), a 3D image from another 4D image (the example above that already works) and a 4D image from a 3D image (the example above where I'm missing the method to reconstruct the 4D).

As I've written I'm looking for a general solution. I'd also like to resample for example a 2D image from a 3D one. But it doesn't seem possible to do slicing in the spatial dimensions with a slicer:

>>> img2DFrom3D=img3D.slicer[:,:,0]
Traceback (most recent call last):
  File "stdin>", line 1, in module>
  File "/home/econdami/.local/lib/python3.7/site-packages/nibabel/spatialimages.py", line 340, in __getitem__.
    slicer = self.check_slicing(slicer)
  File "/home/econdami/.local/lib/python3.7/site-packages/nibabel/spatialimages.py", line 377, in check_slicing
    raise IndexError("Scalar indices disallowed in spatial dimensions; ")
IndexError: Scalar indices disallowed in spatial dimensions; Use `[x]` or `x:x+1`.

Again I don't know enough about nibabel. Is there a solution to do this with nibabel? (and also I don't have a 2D image at hand: the resample_from_to() function works with 2D images ?)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants