在c#中提取matlab传出的多个参数
苦逼的帮别人弄毕设,用的还是自己不会的C#语言,哎,捣鼓了许久,今天终于帮ta快弄完了。今天写博文当然不是来说这些,而是写一点小心得。如题,如何在c#中提取matlab传出的多个参数。
c#没学过,但学过C++,还好,不是文盲。matlab也用过,但不是很熟。今天碰到的事情就是如何在C#中调用matlab。
首先就是配置了,先从别人那学习一些经验。原文地址如下:http://blog.sina.com.cn/s/blog_6622f5c30100hhja.html 。虽然说copy过来有点违反职业道德,但为了以后学习的方便,我也就copy一下了,希望(园园)不要责怪。
朋友电脑配置列表:
(1)Microsoft Visual Studio 2010
(2)Matlab R2012a
(3)window7
1、安装:
首先安装Matlab;
安装Visual Studio;
安装MCRInstall.exe,我安装完Matlab之后在这里找得的:C:"Program Files\MATLAB\R2012a\toolbox\compiler\deploy\win32
配置路径:
点击:我的电脑-属性-高级-环境变量-系统变量-PATH-编辑,在变量值输入框中,不要删除以前的字符串,在最前面加入MCR的安装路径,如:C:"Program Files\MATLAB\MATLAB Compiler Runtime\v80\bin\win32;
确定、保存、重启电脑。
2、 在matlab的Command window中输入mbuild -setup显示如下
>> mbuild -setup Please choose your compiler for building standalone MATLAB applications: Would you like mbuild to locate installed compilers [y]/n? n %选择n Select a compiler: [1] Lcc-win32 C 2.4.1 [2] Microsoft Visual C++ 6.0 [3] Microsoft Visual C++ .NET 2003 [4] Microsoft Visual C++ 2005 [5] Microsoft Visual C++ 2005 Express Edition [6] Microsoft Visual C++ 2008 [7] Microsoft Visual C++ 2010 [0] None Compiler: 4 %选择4,其他编译器可以选相应的选项,我没有验证过 The default location for Microsoft Visual C++ 2010compilers is C:\Program Files\Microsoft Visual Studio 10, but that directory does not exist on this machine.Use C:\Program Files\Microsoft Visual Studio 10.0 anyway [y]/n? y%选择y,因为ta的电脑安装都比较本分,都是默认路径 Please verify your choices: Compiler: Microsoft Visual C++ 20010 Location: C:\Program Files\Microsoft Visual Studio 10.0 Are these correct [y]/n?
y %看上述信息,如果正确选择y Warning: MBUILD requires that the Microsoft Visual C++ 10.0 directories "VC" and "Common7" be located within the same parent directory. MBUILD setup expected to find directories named "Common7" and "VC" in the directory: "C:\Program Files\Microsoft Visual Studio 10". Trying to update options file: C:\Documents and Settings\Administrator\Application Data\MathWorks\MATLAB\R2010a\compopts.bat From template: C:\PROGRA~1\MATLAB\R2010a\bin\win32\mbuildopts\msvc80compp.bat Done . . . 到此matlab编译器设置成功。
3、 编写m文件:
function d=analyse(filePath,rate,pace) %d(1):walk_rateX,步频 %d(2):step_lengthX:步长 %d(3):step_lengthZ:步幅 %filePath:文件的存储路径,请使用绝对路径,string类型 %rate:采样率,int类型 %pace:走路速度,double或float类型 % clear all; A=load(filePath); B=A'; x=B(3,:); % y= B(4,:); z= B(5,:); % x=B(12,:)-10; % y= B(13,:); % z= B(14,:); figure plot(x,'r'); grid on; title('x轴方向加速度'); % figure % plot(y,'g'); % grid on; % title('y轴方向加速度'); figure plot(z,'b'); grid on; title('z轴方向加速度'); [resultX,lagsX] = xcov(x,'unbiased'); % [resultY,lagsY] = xcov(y,'unbiased'); [resultZ,lagsZ] = xcov(z,'unbiased'); Y=resultX; s=kalman(Y); resultX=s; scatterDataX=show(resultX,'x轴方向加速度 自相关系数'); [walk_rateX,step_lengthX]=gaitPara(scatterDataX,rate,pace); d=[]; d(1)=walk_rateX; d(2)=step_lengthX; % figure % plot(resultY,'g'); % grid on; % title('y轴方向加速度 自相关系数'); Y=resultZ; s=kalman(Y); resultZ=s; scatterDataZ=show(resultZ,'z轴方向加速度 自相关系数'); [walk_rateZ,step_lengthZ]=gaitPara(scatterDataZ,rate,pace); d(3)=step_lengthZ; end
代码比较丑,还有其它几个文件,没贴出来。
4、建立matlab工程
在matlab中点击“File- new -Development Project” 自己选择项目保存目录和项目名,如E:"和magicpro.prj 类 型选择.NET Component(忘记是什么了,反正名字有点改了,但还是和.NET最接近的一个),如果你要生成更通用的COM组件,选择Generic COM Component。添加刚才的m文件到这个新建的项目中去。点击Build the project按钮(这个按钮的图标和微软开发工具的Build图标一样)或者右击选择“build”,等待3,4分钟。建立成功。
5、C#中引用,主要是button4_Click()这个方法
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using MathWorks.MATLAB.NET.Arrays;//这里要去刚才安装的那个tool下面找对应的dll,再引入 using butaipro;//这个也需要去刚才建立的matlab工程中找对应的dll文件 namespace test { public partial class Form2 : Form { PersonDB personDB = null; public Form2() { InitializeComponent(); personDB = new PersonDB(); } private void button1_Click(object sender, EventArgs e) { frmDesign frm = new frmDesign(); this.Hide(); frm.Show(); } private void button2_Click(object sender, EventArgs e) { Application.Exit(); } private void button3_Click(object sender, EventArgs e) { Person person = personDB.getPersonInfo(Class1.id); if (null != person) MessageBox.Show("the info is:\n" +person.toStirng()); else MessageBox.Show("查无此人"); //Form3 frm=new Form3(); //frm.Text = TextBox + personDB.Select(); //frmMain frm = new frmMain(); //this.Hide(); //frm.Show(); } private void button4_Click(object sender, EventArgs e) { butaipro.analysis m= new analysis(); MWArray[] argsout = new MWArray[1]; MWArray[] argsin = new MWArray[] { "C:/data/1.txt" ,50,1.2}; m.analyse(3, ref argsout, argsin); MWNumericArray rate = argsout[0] as MWNumericArray; MWNumericArray race_length = argsout[1] as MWNumericArray; MWNumericArray race_range = argsout[2] as MWNumericArray; String s_rate = rate.ToString(); String s_race_length = race_length.ToString(); String s_race_range = race_range.ToString(); MessageBox.Show("步频=" + s_rate + "\n步长=" + s_race_length + "\n步幅=" + s_race_range); } } }
这样就算是一个可以使用的流程了。但是,当matlab中返回的有多个函数时button4_Click()这个方法就要小心了。
6、在c#中提取matlab传出的多个参数
从我上面给出的matlab代码可以看到,返回的是一个数组,经过一个小时的抓狂,button4_Click()中的方法可以获取该数组中的内容了。但如果是返回多个矩阵是,该怎么办?下面是度娘中某位“度哥”的经验:
//输入这里想传入的2个输入参数,为了支持矩阵好通用,所以得弄成Array
double[] a = { 1, 2, 3, 4, 5, 6 };//输入参数1
double[] b = { 2, 4, 6, 8, 10, 12 };//输入参数2
double[,] c = new double[3, 2];//输出参数1
double[,] d = new double[3, 2];//输出参数2
//这些参数都是矩阵
MWNumericArray ma = new MWNumericArray(3, 2, a);//转换成matlab需求的格式
MWNumericArray mb = new MWNumericArray(3, 2, b);
//输出参数是一个MWArray数组
MWArray[] agrsOut = new MWArray[2];//两个输出参数,一定要写数量
//输出几个输出参数可以是不同类型的,比如第一个元素是矩阵,第二个是数值
//同理,输入参数也是一个MWArray数组
MWArray[] agrsIn = new MWArray[] { ma,mb};
//调用函数,输出参数需要加 ref 关键字
myFun.MatrixOpera(2, ref agrsOut, agrsIn);//2表示输入参数的个数,输出结构都在argsOut中,类似于c的指针参数输入
//转换得到实际的输出参数
MWNumericArray x1 = agrsOut[0] as MWNumericArray;
MWNumericArray x2 = agrsOut[1] as MWNumericArray;
c = (double[,])x1.ToArray();
d = (double[,])x2.ToArray();
//一定要注意最后c和d的转化,不同类型的转换差异很大厄
//ToArray()对应n*m的数组
//ToScalarDouble()对应单个数值
//ToVetor()对应1维数组
经过苦苦折磨,发现他里面的有些注释是致命的误读,最主要的就是:
myFun.MatrixOpera(2, ref agrsOut, agrsIn); //2表示输入参数的个数,输出结构都在argsOut中,类似于c的指针参数输入
这个2,不是输入参数的个数,是输出参数的个数,这里表示的是,我输出的是两个MWNumericArray 数组....
当然,接下来就一马平川了,该如何就如何....
匆忙写下来,总感觉自己就是个CV战士,但没办法,自己懂得东西太少了,只能借助于大量的网络巨人的力量,希望自己以后可以改进.......
浙公网安备 33010602011771号