1

I have used interp2 in Matlab, such as the following code, that is part of @rayryeng's answer in: Three dimensional (3D) matrix interpolation in Matlab:

d = size(volume_image)
[X,Y] = meshgrid(1:1/scaleCoeff(2):d(2), 1:1/scaleCoeff(1):d(1));
for ind = z
    %Interpolate each slice via interp2   
    M2D(:,:,ind) = interp2(volume_image(:,:,ind), X, Y);   
end

Example of Dimensions:

The image size is 512x512 and the number of slices is 133. So:
volume_image(rows, columns, slices in 3D dimenson) : 512x512x133 in 3D dimenson
X: 288x288
Y: 288x288
scaleCoeff(2): 0.5625
scaleCoeff(1): 0.5625
z = 1 up to 133 ,hence z: 1x133
ind: 1 up to 133
M2D(:,:,ind) finally is 288x288x133 in 3D dimenson

Aslo, Matlabs syntax for size: (rows, columns, slices in 3rd dimenson) and Python syntax for size: (slices in 3rd dim, rows, columns). However, after convert the Matlab code to Python code occurred an error, ValueError: Invalid length for input z for non rectangular grid:

for ind in range(0, len(z)+1):
    M2D[ind, :, :] = interpolate.interp2d(X, Y, volume_image[ind, :, :]) # ValueError: Invalid length for input z for non rectangular grid

What is wrong? Thank you so much.

Ellie
  • 303
  • 2
  • 16
  • How did you create `volume_image`? Usually, in Python, arrays are stored in C order, not F order like Matlab, so it would be `volume_image[:, :, ind]`. Also the range is wrong, you want to use `for ind in range(len(z):`. – Matthieu Brucher Oct 26 '18 at 08:12
  • @ Matthieu Brucher: I found out: Matlabs syntax for `size: (x = rows, y = columns, z = slices in 3D dimenson)` and Python syntax for `size: [z = slices in 3D dim, x = rows, y = columns] ` and also, the range of `for` is the same as Matlab. I edited my example in the question. – Ellie Oct 26 '18 at 08:58
  • How did you read your image? You still have an error with `len(z)` and why is z not a vector but a matrix?. – Matthieu Brucher Oct 26 '18 at 08:59
  • @ Matthieu Brucher: I collect the images as `volume_image[i, :, :] = dcm_image.pixel_array` in a loop. `z` is number of slices in 3rd dimension.The error is because of `interp2d` and not `len(z)`. – Ellie Oct 26 '18 at 09:16
  • You may want to use scikit.image instead. `len(z)` is an error, but I would say that the content of `volume_image` also doesn't allow a good interpolation. But we don't have its content. – Matthieu Brucher Oct 26 '18 at 09:24
  • In each iteration of `for` loop, the content of `volume_image` is an image with a size of 512x512, and using `ind` we can access the 133 images (in 3rd dimension). – Ellie Oct 26 '18 at 09:38
  • Possible duplicate of [Problems porting Matlab interp2 to SciPy interp2d](https://stackoverflow.com/questions/23567252/problems-porting-matlab-interp2-to-scipy-interp2d) – Matthieu Brucher Oct 26 '18 at 09:39
  • Have you looked at the linked post? – Matthieu Brucher Oct 26 '18 at 10:52
  • Yes, but the problem isn't solved yet! – Ellie Oct 26 '18 at 10:55
  • So what is missing compared to the link? – Matthieu Brucher Oct 26 '18 at 10:55
  • @Matthieu Brucher: I have read the answers: "instead of giving `X` and `Y` as the matrix outputs from meshgrid, it just takes a `single row` and a `single column` vector. " then I have used it but one error is found: `interpolate.RectBivariateSpline(X, Y, volume_image[ind, :, :])` is used and the error is: `ValueError: x dimension of z must have same number of elements as x`. – Ellie Oct 26 '18 at 11:08
  • Try scikit.image, it's meant for interpolation of images. – Matthieu Brucher Oct 26 '18 at 11:10
  • http://scikit-image.org/docs/dev/auto_examples/transform/plot_edge_modes.html – Matthieu Brucher Oct 26 '18 at 13:35
  • @Matthieu Brucher: I checked [link](http://scikit-image.org/docs/dev/auto_examples/transform/plot_edge_modes.html) but couldn't be helped. – Ellie Oct 26 '18 at 19:21

2 Answers2

2

In MATLAB, interp2 has as arguments:

result = interp2(input_x, input_y, input_z, output_x, output_y)

You are using only the latter 3 arguments, the first two are assumed to be input_x = 1:size(input_z,2) and input_y = 1:size(input_z,1).

In Python, scipy.interpolate.interp2 is quite different: it takes the first 3 input arguments of the MATLAB function, and returns an object that you can call to get interpolated values:

f = scipy.interpolate.interp2(input_x, input_y, input_z)
result = f(output_x, output_y)

Following the example from the documentation, I get to something like this:

from scipy import interpolate
x = np.arange(0, volume_image.shape[2])
y = np.arange(0, volume_image.shape[1])
f = interpolate.interp2d(x, y, volume_image[ind, :, :])
xnew = np.arange(0, volume_image.shape[2], 1/scaleCoeff[0])
ynew = np.arange(0, volume_image.shape[1], 1/scaleCoeff[1])
M2D[ind, :, :] = f(xnew, ynew)

[Code not tested, please let me know if there are errors.]

Cris Luengo
  • 55,762
  • 10
  • 62
  • 120
  • There is an error: `ValueError: could not broadcast input array from shape (288,1024) into shape (288,288)`. I want to resize an image with the size of `512x512` to `288x288`. – Ellie Oct 26 '18 at 20:35
  • @eli: Maybe I misinterpreted your definition of `scaleCoeff`. Make usre that `xnew` and `ynew` each have 288 elements. – Cris Luengo Oct 26 '18 at 20:44
  • Yes, it was because of `scaleCoeff`. My problem is solved. Thank you so much. – Ellie Oct 26 '18 at 20:56
0

You might be interested in scipy.ndimage.zoom. If you are interpolating from one regular grid to another, it is much faster and easier to use than scipy.interpolate.interp2d.

See this answer for an example: https://stackoverflow.com/a/16984081/1295595

You'd probably want something like:

import scipy.ndimage as ndimage
M2D = ndimage.zoom(volume_image, (1, scaleCoeff[0], scaleCoeff[1])
craq
  • 1,441
  • 2
  • 20
  • 39