0

I want to call Matlab .m-files and functions in Python, but because of different data type between Matlab and Python, an error occurs about TypeError: unsupported Python data type: numpy.ndarray.

As an example in the below code, VoxelSizeUnification is a Matlab function that I want to call it in Python and its inputs are from Python data types:

import matlab.engine
eng = matlab.engine.start_matlab()

xyzSpacing = [dcm_image.SliceThickness, dcm_image.PixelSpacing[1], dcm_image.PixelSpacing[0]]
xyzNewSpacing = [1.25, 1.25, 1.25]
eng.VoxelSizeUnification(volume_image, xyzNewSpacing, xyzSpacing)  # TypeError: unsupported Python data type: numpy.ndarray

that:

volume_image is {ndarray} and includes images as: volume_image[number of slices in 3rd dimenson = 133, rows=512, columns=512].
xyzNewSpacing and xyzSpacing are <class 'list'> with size of (1 x 3)

Also, I searched using link1, but I don't want to save files and then load them. Also in link2, mlab should work with python>=2.7 and my Python is 3.6.6 and Matlab 2017b.

Also, I have tried by matlab.double and tested above code with an example, without any error:

xyzNewSpacing = matlab.double([1.25, 1.25, 1.25])
xyzSpacing = matlab.double([1.5, 1.5, 1.5])
vol = matlab.double([[[1, 2, 1], [3, 1, 5], [2, 1, 2]],
                     [[2, 3, 1], [1, 2, 3], [2, 1, 3]],
                     [[4, 2, 1], [2, 3, 1], [3, 2, 1]]])
ret = eng.VoxelSizeUnification(vol, xyzNewSpacing, xyzSpacing)

But for volume_image that is a 3D array of images, I receive an error about: ValueError: initializer must be a rectangular nested sequence.

Python:

xyzNewSpacing = matlab.double([1.25, 1.25, 1.25])
xyzSpacing = matlab.double([1.5, 1.5, 1.5])
d = matlab.double(volume_image) # ValueError: initializer must be a rectangular nested sequence
ret = eng.VoxelSizeUnification(d, xyzSpacing, xyzNewSpacing)

Matlab:

function outputSize = VoxelSizeUnification(d, xyzSpacing, xyzNewSpacing)
         outputSize = [ceil((d(1)*xyzSpacing(1))/xyzNewSpacing(1))...
                      ceil((d(2)*xyzSpacing(2))/xyzNewSpacing(2))...
                       ceil((d(3)*xyzSpacing(3))/xyzNewSpacing(3))];
end

What is the reason of ValueError: initializer must be a rectangular nested sequence? Thanks.

Ellie
  • 303
  • 1
  • 10
  • Did you try [`matlab.double`](https://www.mathworks.com/help/matlab/matlab_external/matlab-arrays-as-python-variables.html) as the second answer in your first link described? – excaza Oct 30 '18 at 11:17
  • @excaza: Yes, but because of `volume_image` that is a 3D array, I receive an error about: `ValueError: initializer must be a rectangular nested sequence`. For example, If we have `xyzNewSpacing = matlab.double([1.25, 1.25, 1.25])`, `xyzSpacing = matlab.double([1.5, 1.5, 1.5])` , `d = matlab.double(volume_image)` , `ret = eng.triarea(d, xyzSpacing, xyzNewSpacing)` and `ret = np.array(ret)`, that error occurs. – Ellie Oct 30 '18 at 11:33

2 Answers2

1

The error was because of datatypes and using volume_image = volume_image.tolist() the error was solved. However, it was taken a lot of running time. So, if everyone has a good idea please share it.

Ellie
  • 303
  • 1
  • 10
0

Have you tried using mlabwrap?

Check this link out- might be of some help

Calling MATLAB .m-files and functions in Python script

HellHammer
  • 85
  • 7
  • Yes, I search for an equivalent datatype between Python and Matlab. I have checked [Matlab](https://www.mathworks.com/help/matlab/matlab_external/pass-data-to-matlab-from-python.html) and I have used `list` or `tuple` but they couldn't be solved the error. Also [mlab](https://stackoverflow.com/questions/13457751/calling-matlab-m-files-and-functions-in-python-script) should work with python>=2.7 and my Python is 3.6.6. – Ellie Oct 30 '18 at 08:57