Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
302 views
in Technique[技术] by (71.8m points)

Passing Argument to MATLAB Function in Python Results in Error: Size inputs must be numeric

I'm currently working on a python script that passes an argument to a function getWeight.m written in MATLAB.

getWeight.m returns a weight matrix with the same dimensions given the size of an RGB image. It's source code can be found here.

I'm running the following python script:

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

import cv2

image = cv2.imread('warped_image.png')

weight = eng.getWeight(image.shape) # (575, 503, 3)
print(weight)

Passing image.shape of class tuple as an argument to the function yields the following error:

Size inputs must be numeric

Are there any workarounds to this error?

Here's the error after following @Chris method:

Traceback (most recent call last):
  File "test.py", line 10, in <module>
    weight = eng.getWeight(matlab.int8(list(image.shape))
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/matlab/
mlarray.py", line 106, in __init__
    raise ex
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/matlab/
mlarray.py", line 104, in __init__
    super(int8, self).__init__('b', initializer, size, is_complex)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/matlab/
_internal/mlarray_sequence.py", line 57, in __init__
    self._data = flat(self, initializer, init_dims, typecode)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/matlab/
_internal/mlarray_sequence.py", line 338, in flat
    return array.array(typecode, nested_list)
OverflowError: signed char is greater than maximum

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Check out how matlab converts python types: https://www.mathworks.com/help/matlab/matlab_external/pass-data-to-matlab-from-python.html

A python tuple will be converted to a matlab cell array, so in your getWeight function when you access the indeces with size(3) you're selecting a cell rather than the value of the cell.

You can change your getWeight function to pull out the values of the cells (e.g., size{3}) and it should work. If this function is used in many other places you may want to add some checks within getWeight to see if size is a normal array (when it should use size(3)) vs a cell array.

You could also change the input to accept integers instead, e.g., getWeight(s1,s2,s3) and then call it with eng.getWeight(image.shape[0],image.shape[1],image.shape[2]). But again, if getWeight is used elsewhere you'll have to refactor every call.

Finally, you could try converting the tuple to a "matlab numeric array object" and then passing that array to getWeight. See the documentation here for how to create a matlab array in python: https://www.mathworks.com/help/matlab/matlab_external/matlab-arrays-as-python-variables.html I don't have matlab on my present computer, but I believe the following code would work:

import matlab.engine

eng = matlab.engine.start_matlab()

import cv2

image = cv2.imread('warped_image.png')

weight = eng.getWeight(matlab.int8(image.shape))
print(weight)

The examples of creating the matlab arrays in the matlab documentation all use lists (for example A = matlab.int8([1,2,3,4,5])), so you may need to convert that image.shape tuple to a list, but I suspect the tuple will work...


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
...