6

I have 3D image of a brain (let's call it flash) and it's currently 263 x 256 x 185. I want to resize it to be the size of another image(call it whole_brain_bravo); 256 x 256 x 176, and (hopefully) use a lanczos interpolation to resample (Image.ANTIALIAS). My (failed) attempt:

from scipy import ndimage as nd
import nibabel as nib
import numpy as np



a = nib.load('flash.hdr') # nib is what I use to load the images
b = nib.load('whole_brain_bravo.hdr')

flash = a.get_data() # Access data as array (in this case memmap)
whole = b.get_data()

downed = nd.interpolation.zoom(flash, zoom=b.shape) # This obviously doesn't work

Have you guys ever done this sort of thing on a 3D image?

faskiat
  • 689
  • 2
  • 6
  • 21

2 Answers2

4

From the docstring for scipy.ndimage.interpolate.zoom:

"""
zoom : float or sequence, optional
    The zoom factor along the axes. If a float, `zoom` is the same for each
    axis. If a sequence, `zoom` should contain one value for each axis.
"""

What is the scale factor between the two images? Is it constant across all axes (i.e. are you scaling isometrically)? In that case zoom should be a single float value. Otherwise it should be a sequence of floats, one per axis.

For example, if the physical dimensions of whole and flash can be assumed to be equal, then you could do something like this:

 dsfactor = [w/float(f) for w,f in zip(whole.shape, flash.shape)]
 downed = nd.interpolation.zoom(flash, zoom=dsfactor)
ali_m
  • 71,714
  • 23
  • 223
  • 298
  • This is actually good thanks. Would you also know how to resample downed by any chance? – faskiat Aug 22 '13 at 17:24
  • That's what `np.interpolation.zoom` does to produce `downed` from `flash`! You can change the order of the spline interpolation it uses via the `order=` parameter (I'm not aware of any implementation of Lanczos interpolation in numpy/scipy). – ali_m Aug 22 '13 at 17:28
  • Ah, I see what you mean. I was hoping I could use Lanczos. It isn't that big of a deal though. And yes lanczos is implemented in the python imaging library; Image.ANTIALIAS is actually a 3-lobe lanczos written in C (according to the documentation) – faskiat Aug 22 '13 at 17:36
  • As I'm sure you're already aware, PIL only handles 2D images, so you would be limited to resampling 2D slices of your array. I honestly don't think you'd see much practical difference between Lanczos and cubic spline interpolation anyway. – ali_m Aug 22 '13 at 18:04
2

According to the docs, the zoom argument is "The zoom factor along the axes". That's a little vague, but it sounds like they mean a scale factor, rather than the desired dimension.

Try this:

zoomFactors = [bi/float(ai) for ai, bi in zip(a, b)]
downed = nd.interpolation.zoom(flash, zoom=zoomFactors) 

Not sure about choosing a filter - the docs only mention spline interpolations of various orders.

Brionius
  • 13,858
  • 3
  • 38
  • 49
  • How would you go about resampling a 3D image in python in general? Like say I give you an image, and you look at it and go "oh this looks crap, I should probably do some nearest neighbour to make it a little nicer", how would you do it? – faskiat Aug 22 '13 at 17:29
  • 1
    In what sense would downsampling an image ever make it look *nicer*? If I wanted to resample an array, I guess I would try using scipy.ndimage.interpolation.zoom. Is that not working for you? I'm sure there are plenty of ways to do it, but unless you describe why this one isn't good enough, I can't help ya. – Brionius Aug 22 '13 at 17:37
  • It's not that it isn't good enough, I just really like the results that lanczos scheme has when downsampling, say, a jpeg so I wanted to maybe reproduce it in a 3d image. But it isn't a big deal, spline is fine (hehe I rhymed). Thanks for your help! – faskiat Aug 22 '13 at 17:42
  • Ah, I see. I'll look around, but I don't know of a way to use the Lanczos filter for 3D resampling off the top of my head - good luck! – Brionius Aug 22 '13 at 17:50
  • @elefun , would interpolation.zoom with order=0 not work for nearest-neighbor downsampling? – adalca Feb 21 '17 at 18:12