python调用matlab函数_从 Python 调用 MATLAB 函数的三种方法

0. 实验环境Ubuntu 16.04

Matlab R2015b

1. 借助于 mlab 库

安装方法非常简单,只需一行命令 sudo pip install mlab 即可。

import numpy as np

from PIL import Image

from mlab.releases import latest_release as matlab

image = Image.open('1.jpg')

image = np.array(image)

h, w = image.shape

print(image.shape) # (413, 295)

在上面的代码中,我们先读入一个图片,然后将其转化为一个 Numpy 数组。接下来,假如我们想通过调用 MATLAB 的 imresize 函数来对这幅图像进行 4 倍上采样,那么我们要做的就是将这个 Numpy 数组传递到 MATLAB 中,然后调用相应的函数,最后再将结果返回到 Python 中。

但是,MATLAB 并不支持将 Python 中的 Numpy 数组直接映射为矩阵,具体映射方式可参考 matlab.double(initializer=None, size=None, is_complex=False) 构造函数

image = image.reshape(-1, 1)

image = image.tolist()

image = matlab.double(image)

image = matlab.reshape(image, (h, w))

resized_image = matlab.imresize(image, 4, 'bicubic')

print(resized_image.shape) # (1652, 1180)

如果我们想要调用自定义函数,比如下面这样的 m 文件。

function c = add(a, b)

c = a + b;

end

那么只需要传递相应的参数进去即可,这里 Python 中的浮点数会映射为 MATLAB 中的 double 类型。

result = matlab.add(2.0, 3.0)

print(result) # 5.0

但是,目前在我这边发现 mlab 不支持 Python 3,安装后会提示 ImportError: No module named 'mlabwrap' 之类的错误,暂时还没找到解决方案。

2. 借助于 MATLAB 自带的引擎 API

首先,需要 /usr/local/MATLAB/R2015b/extern/engines/python,然后运行命令 sudo python setup.py install 即可。

由于我的 MATLAB 版本还比较低,目前只支持到 Python 3.4,更高的版本则会报错 OSError: MATLAB Engine for Python supports Python version 2.7, 3.3 and 3.4, but your version of Python is 3.5。

>>> import matlab.engine

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

>>> import numpy as np

>>> image = np.random.randn(30, 30)

>>> image.shape

(30, 30)

>>> resized_image = eng.imresize(image, 4, 'bicubic')

Traceback (most recent call last):

File "", line 1, in

File "/usr/local/lib/python2.7/dist-packages/matlab/engine/matlabengine.py", line 79, in __call__

out=_stdout, err=_stderr)

TypeError: unsupported Python data type: numpy.ndarray

>>> image = image.reshape(-1, 1)

>>> image = image.tolist()

>>> image = matlab.double(image)

>>> image.reshape((30, 30))

>>> resize_image = eng.imresize(image, 4, 'bicubic')

>>> resize_image.size

(120, 120)

>>> eng.add(2.0, 3.0)

5.0

>>>

用法和第一种类似,但是在我这边测试发现只能运行在交互模式下,直接运行对应的 py 文件则会报错。

senius@HP:~/Downloads$ python2 test1.py

Traceback (most recent call last):

File "test1.py", line 3, in

import matlab.engine

File "/usr/local/lib/python2.7/dist-packages/matlab/engine/__init__.py", line 60, in

raise EnvironmentError('The installation of MATLAB Engine for Python is '

EnvironmentError: The installation of MATLAB Engine for Python is corrupted.

Please reinstall it or contact MathWorks Technical Support for assistance.

上面两种方法都只能进行一些简单的调用,而且还需要在 Python 和 MATLAB 之间进行数据转化,非常不方便,下面介绍的第三种方法则非常简单有效。

3. 借助于 transplant 库

sudo pip3 install transplant。Python 中的列表会转化为 MATLAB 中的元胞数组,Numpy 数组会转化为 MATLAB 中的矩阵,更多详细信息可参阅

>>> import transplant

>>> import numpy as np

>>> matlab = transplant.Matlab(jvm=False, desktop=False)

< M A T L A B (R) >

Copyright 1984-2015 The MathWorks, Inc.

R2015b (8.6.0.267246) 64-bit (glnxa64)

August 20, 2015

For online documentation, see http://www.mathworks.com/support

For product information, visit www.mathworks.com.

>>> image = np.random.randn(30, 30)

>>> image.shape

(30, 30)

>>> resized_image = matlab.imresize(image, 4, 'bicubic')

>>> resized_image[0]

array([[ 0.78619134, 0.7167187 , 0.57147529, ..., -0.1314248 ,

-0.19615895, -0.22226921],

[ 0.69992414, 0.63668882, 0.50463212, ..., -0.10023177,

-0.16053713, -0.18483134],

[ 0.51579787, 0.46606682, 0.36253926, ..., -0.01897913,

-0.07015085, -0.09065985],

...,

[ 0.27508006, 0.27579099, 0.28756401, ..., -0.70385557,

-0.80006309, -0.84680474],

[ 0.23260259, 0.23527929, 0.25076149, ..., -0.75840955,

-0.80315767, -0.82872907],

[ 0.21943022, 0.2228168 , 0.2396492 , ..., -0.78075353,

-0.80353953, -0.8200766 ]])

>>> resized_image[0].shape

(120, 120)

>>>

针对如下所示的多个自定义函数存在互相调用的复杂情况,transplant 也可以轻松胜任。

比如,我们需要通过 Python 调用 NGmeet_DeNoising( N_Img, O_Img, nSig ) 这个函数,它有三个输入,N_Img 为长×宽×波段的三维噪声高光谱图像,O_Img 为对应的干净图像,而 nSig 为噪声等级。那么只需在 Python 中将两个 Numpy 数组和一个整数传给对应的函数即可。

clean = np.load('GT_crop.npy')

h, w, b = clean.shape

sigma = 25

noisy = clean + np.random.randn(h, w, b) * sigma / 255

print(cal_psnr(clean, noisy)) # 20.1707

c = matlab.NGmeet_DeNoising(255.0*noisy, 255.0*clean, sigma)

print(c.shape, c.dtype) # (200, 200, 191) float64

print(matlab.mpsnr(c/255, clean)) # 34.5712

如果报如下的错误,则因为 par_nSig 是将 Python 中的 sigma=25 转化为了 MATLAB 中的 int64,而 int64 数据不能与 double 类数据相乘。而解决办法也很简单,double(par_nSig) 将其数据转化为 double 类型即可。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值