如何在MATLAB中调用“用Python写成的函数或脚本”,首先要确保MATLAB知道咱们的Python解释器的位置在哪里。
如果安装了Python的时候把Python加入了系统环境变量,则MATLAB就是知道Python解释器的位置在哪里的,如下图所示:
从上图可看出,我的系统环境变量里是添加了Python解释器的路径了的。此时在MATLAB的命令行窗口中输入命令“pyversion”,就可以显示Python解释器的相关信息了,如下图所示:
如果系统环境变量中没有加入Python解释器的路径,那么在MATLAB的主页窗口点击“设置路径”,添加python的安装目录(选择“添加并包含子文件夹”),就可以自动添加python目录下的路径。
做好上面的准备工作后,我们就可以调用用Python写成的函数或脚本了。
接下来我们就来具体看一看各种调用情况。
目录
- 1 调用Python本身的库函数
- 2 调用自己写的py文件中的某个函数
- 3 调用某个类中的某个成员函数
- 4 调用python某个扩展库中的某个函数
- 5 在MATLAB中运行Python脚本
1 调用Python本身的库函数
以调用Python本身函数print()为例,可以像下面这样调用。
py.print('Hello world!');
运行结果如下图所示:
2 调用自己写的py文件中的某个函数
首先把这个py文件放于自己的MATLAB目录下,或者添加到MATLAB的路径,然后按下面的例子调用自己写的函数。
我的py文件名为test_call.py,放置于MATLAB目录下,截图如下:
test_call.py的内容如下:
def func(a, b):
print('变量a乘以变量b的值为:{}'.format(a * b))
func(2, 4)
我们在MATLAB中调用这个文件中的函数func(),那么可以用下面这条MATLAB语句调用:
py.test_call.func(2,5);
运行结果如下:
注意:如果自己写的python函数有返回值,比如把上面的py文件改成如下的内容:
def func(a, b):
print('变量a乘以变量b的值为:{}'.format(a * b))
c = a+b
return c
func(2, 4)
那么MATLAB将因为跨语言而收不到这个返回值,此时我们运行下面这条MATLAB语句:
x = py.test_call.func(2,5);
x中的结果如下:
可见,x并没有得到我们想要的返回值,我们希望能到的返回值是c=2+4=6。
3 调用某个类中的某个成员函数
这个的方法和第2个是一样的,相关代码和截图如下:
类myClass的相关情况如下:
class myClass:
version = 1.0
def __init__(self,a,b):
self.a, self.b = a,b
def getsum(self):
print('变量a加上变量b的值为:{}'.format(self.a+self.b))
在MATLAB调用类myClass的成员函数getsum(),操作如下:
%先实例化一个类myClass的对象pyObj
pyObj = py.myClass.myClass(1,2);
%调用类myClass的成员getsum()
pyObj.getsum();
运行结果如下:
这里要特别注意:这种情况下如果我们对我们调用的类进行了修改更新,那么,这种情况下matlab中会使用缓存中的类,而不会使用修改更新后的类。
比如我把上面代码中的成员函数getsum()的语句:
print('变量a加上变量b的值为:{}'.format(self.a+self.b))
改为
print('变量a减上变量b的值为:{}'.format(self.a-self.b))
再运行,依然是先前的运行结果,如下截图所示:
解决这个问题的办法为在相应的MATLAB前加上下面这三条命令:
clear classes;
mod = py.importlib.import_module('myClass');
py.importlib.reload(mod);
这样操作后我们就能得到我们修改后的结果了,加上上面三条命令的MATLAB代码如下:
clear classes;
mod = py.importlib.import_module('myClass');
py.importlib.reload(mod);
%先实例化一个类myClass的对象pyObj
pyObj = py.myClass.myClass(1,2);
%调用类myClass的成员getsum()
pyObj.getsum();
运行结果如下图所示:
通过上面的叙述可见,在MATLAB中是可以进行Python类的实例化操作和成员调用的。
再仔细深思,其实这并不是MATLAB在调用Python,而是此时MATLAB充当了Python的一个IDE的角色,为了说明这一点,我们继续往下看,看下面的第4种情况。
4 调用python某个扩展库中的某个函数
这里我们调用Python-OpenCV中的函数cv2.imread()、cv2.imshow()、cv2.waitKey(),实现读取并显示一幅图像。
MATLAB代码如下:
src = py.cv2.imread("F:/material/images/P0036-view-256_256.jpg");
py.cv2.imshow('MATLAB-src',src);
py.cv2.waitKey();
运行结果如下:
从上图可以看出,src是类numpy.ndarray的一个对象,如下图所示:
从这个示例也更应证了咱们是在MATLAB中运行python语句,而不是在MATLAB中调用python的函数,如果是严格意义上的调用的话,其返回值应该是MATLAB的数据类型才对,此时MATLAB类似于一个python的IDE的角色。
5 在MATLAB中运行Python脚本
这个可以用MATLAB的函数system()实现,关于MATLAB的函数system(), 比如我们要在MATLAB中运行python脚本“test_call.py”,可以像下面这样操作:
(当然,下面的操作建立在已安装Python解释器并且配置了Python解释器的系统环境的基础上)
command = 'test_call.py &'; %cd是cmd中用于显示当前路径的命令
[status,cmdout] = system(command,'-echo');
test_call.py 中的内容如下:
import cv2
src = cv2.imread("F:/material/images/P0036-view-256_256.jpg")
cv2.imshow('src_img', src)
cv2.waitKey()
运行结果如下:
可见正确显示了图片。
提问:为什么要写成
command = 'test_call.py &';
而不写成
command = 'test_call.py';