最近在做图像处理方面的项目,需要用C#与Matlab相结合,之前是采用matlab生成dll给C#调用,但是速度比较慢,所以改为直接调用Matlab的引擎了。
本人的开发环境是Matlab2016a和VS2013,由于是调用matlab引擎,所以必须安装Matlab。
安装好后就可以进行开发了。
1、首先在工程中引用Matlab Application(Version 9.0)Type libaray,不同版本matlab对应的库的版本也不一样。
添加引用后,引用目录下多了一个MLApp文件,如果在编程是采用MLAppClass的话还需要将该文件的属性Embed Interop Types的True值改为False,不然会报错。
如果采用MLApp.MLApp则不会报错。
MLApp.MLApp matlab = null;
Type matlabAppType = System.Type.GetTypeFromProgID("Matlab.Application");
matlab = System.Activator.CreateInstance(matlabAppType) as MLApp.MLApp;
string command;
command = "t=2:0.2:4*pi;y=sin(t);h = plot(t,y)";
String path = Directory.GetCurrentDirectory();//获取当前路径
matlab.Visible = 0;
matlab.Execute(command);
command = @"print(gcf, '-djpeg', '" + path + "\\Test1');close all";//保存图片
matlab.Execute(command);
自己写了个function:
function [out1, out2] = add(x, y)
out1 = x+ y;
out2 = x * y;
M文件其实可以随便放在哪里,只要将M文件的目录设为工作目录就可以(这里的设置是在C#代码里设置,而不是在Matlab软件中设置),这里就先放在工程运行目录下,即Debug文件夹下。
注意:如果第一次采用C#调用Matlab引擎不设置工作目录,那么工作目录就是这次工程运行目录:假设这次工程运行目录是A,以后你所有C#调用Matlab的工作目录都是A了,如果你下次新建了另一个工程(工程的运行目录为B)没有设置工作目录,那么该工作目录还是A,而不是目录B。后面会详细讲解
C#里调用add.M:
MLApp.MLApp matlab = null;
Type matlabAppType = System.Type.GetTypeFromProgID("Matlab.Application");
matlab = System.Activator.CreateInstance(matlabAppType) as MLApp.MLApp;
//string path_project = Directory.GetCurrentDirectory(); //工程文件的路径,如bin下面的debug
//string path_matlab = "cd('" + path_project + "')"; //自定义matlab工作路径 这里我注释调用
//matlab.Execute(path_matlab);
//matlab.Execute("clear all");//这条语句也很重要,先注释掉,下面讲解
string command;
command = @"[a,b]=add(6,3)";
matlab.Execute(command);
try
{
var retult = matlab.GetVariable("a", "base");//获取结果,就是传入base字符串,而不是其他的。
var retult2 = matlab.GetVariable("b", "base");
}
catch (Exception)
{
throw;
}
function [out1, out2] = add(x, y)
out1 = x+ y+10;
out2 = x * y*10;
再次运行,运行结果如下:发现结果和预想的不一样,
matlab.Execute("clear all");
再次运行:
function out = minus2(x, y)
out = x- y;
运行下面代码:
MLApp.MLApp matlab = null;
Type matlabAppType = System.Type.GetTypeFromProgID("Matlab.Application");
matlab = System.Activator.CreateInstance(matlabAppType) as MLApp.MLApp;
//string path_project = Directory.GetCurrentDirectory(); //工程文件的路径,如bin下面的debug
//string path4_matlab = "cd('" + path_project + "')"; //自定义matlab工作路径
//matlab.Execute(path4_matlab); 这里注释掉了,下面会将为什么
matlab.Execute("clear all");
string command;
command = @"a=minus2(10,4)";
//command = @"feature_crack = BridgeFeature( 'C:\Users\Administrator\Desktop\测试\',0)";
matlab.Execute(command);
try
{
var result = matlab.GetVariable("a", "base");
Console.WriteLine("result=" + result);
}
catch (Exception)
{
throw;
}
所以在C#里面添加图中的代码,运行结果如下:结果就正确了!
总结:
1、C#中要进行清除变量操作,否则改变M文件里的内容,C#运行时的结果还是原来修改之前的,
2、C#工程中要进行matlab工作路径的添加,否则将会报错,
3、当M文件函数的输入时有字符串变量时,那么在C#中写命令语句时,该参数需要加单引号,下图中的BridgeFeature第一次参数为字符串类型,所以要加单引号
这几个坑花了我好久的时间,希望给大家一个参考,少走些弯路。