目前高校或者研究所的研究人员在开发算法时,都习惯并热衷于使用Matlab进行算法开发,但是对于实际工程项目中,后端程序大部分都是拿Java、C#或者Python进行后台开发。如果想用Matlab算法必须通过上述后端语言对Matlab算法实现调用,将其封装为一个函数,就可以在后台进行调用了。笔者当前项目是利用Flask(Python)作为后台,所以想到用Python对Matlab实现调用。网上关于Python调用Matlab的算法有很多,但大多数都不是很好用。笔者经过反复调试,得到一种解决方案,效果较好,与大家共享。
python代码
import os
import sys
import tempfile
import matlab
import matlab.engine
class MatlabFile(object):
def __init__(self, work_dir: str, input_matlab_file_path: str):
with open(input_matlab_file_path, 'rb') as f:
data = f.read()
self.temp_file = tempfile.NamedTemporaryFile(dir=work_dir, delete=False, suffix=".m")
self.temp_file.write(data)
self.temp_file.close()
self.parent_dir = os.path.split(self.temp_file.name)[0]
self.name = os.path.split(os.path.splitext(self.temp_file.name)[0])[1]
def delete(self):
"""删除临时文件"""
os.remove(self.temp_file.name)
def main():
# 加载算法文件
# a2_path = "C:\\algo_file\\model.m"
a2_path = "model.m"
algorithm_file = MatlabFile(
work_dir=os.path.abspath("C:\\temp"),
input_matlab_file_path=a2_path
)
userpath_file = MatlabFile(
work_dir=os.path.abspath("C:\\temp"),
input_matlab_file_path="userpath_modified.m"
)
# 初始化MATLAB引擎
engine = matlab.engine.start_matlab()
engine.userpath_modified(algorithm_file.parent_dir) # 让matlab去哪里找算法文件
userpath_file.delete()
# 传入参数,并调用MATLAB算法
u_real = matlab.double([[10]])
y_real = matlab.double([[10]])
F = matlab.double([[0.00000005]])
Q = matlab.double([[0.00000002]])
delta_y = matlab.double([[0]])
try:
result = getattr(engine, algorithm_file.name)(
u_real, y_real, F, Q, delta_y, nargout=1
)
except matlab.engine.MatlabExecutionError as err:
algorithm_file.delete()
print(err, file=sys.stderr)
exit()
# 得到算法结果
print(result)
# 删除临时算法文件,释放资源
algorithm_file.delete()
engine.exit()
if __name__ == '__main__':
fileNamePath = "c:\\temp" # 临时文件夹路径
if os.path.exists(fileNamePath): # 如果文件存在
os.rmdir(fileNamePath) # 先删除
os.mkdir(fileNamePath) # 再新建文件夹
main()
简单说明
- 算法路径:笔者调用的Matlab算法是保存在 a2_path中的相对路径下的文件model.m(也可以使用绝对路径,可以更改到自己需要的算法路径,如程序所示)。
- 存放算法临时文件:在C盘下建立一个temp临时文件夹,当然也可以自己更改临时文件夹存放的路径和名称,即更改代码中所有涉及到"c:\temp"的部分。如果忘记新建临时文件夹了,运行该程序后,也可以在相应目录下自行建立,(–main–)函数中有详细注解。需要注意的是,temp在程序执行前必须为空文件夹。如果上述程序执行完毕没错误,temp文件夹会自动清空,但如果程序在中间某个过程出错了,临时文件夹中的内容可能没清理掉,这时候就要手动清理了。
- main函数:python调用Matlab具体过程:
- 开启Matlab引擎
- 调用Matlab算法
- 关闭Matlab引擎
- userpath_modified.m文件:将该文件放在程序的根目录下,调用这个文件可以解决python调用Matlab偶尔出现乱码的错误。
- 注意传入MATLAB的输入参数如果是数字的话是double型。
- try中就是python调用MATLAB具体过程,注意对应的输入参数,nargout=1表示输出结果为一个值。
完整代码
https://download.csdn.net/download/xiecheng1995/11260246
上述程序下载后可直接运行,开启MATLAB引擎可能会需要7~10s,请耐心等待。
注意
- 在对应Python编译器下安装matlab第三方库
- 在matlab安装目录中的 E:\MATLABR2016b\extern\engines\python(我的安装目录) 下执行 python setup.py install (最好是在Pycharm的命令行中执行)
- 测试版本: Python版本3.5,matlab版本MATLAB R2016b
本人原创,转载请标明出处,谢谢合作!