您的位置 首页 动态

Matlab强壮的数组处理功用怎么处理图画处理解析计划

基于COM组件的Matlab与C++混合编程方式因拥有独立的运行环境和两种语言的互补优势而被众多科研人员和编程人员所接受,同时也是MathWorks公司推荐使用的混编方式。但在程序设计过程中,通常会遇

根据COM组件的Matlab与C++混合编程办法因具有独立的运转环境和两种言语的互补优势而被很多科研人员和编程人员所承受,一起也是MathWorks公司引荐运用的混编办法。但在程序设计进程中,一般会遇到两个难点问题:(1)二维数组参数的传递与输出; (2)Matlab生成图形嵌入VC工程界面中。关于榜首个问题,Bruce McKinney[1]在MSDN上指出;“假如对一维数组进行操作,则SAFEARRAY函数变的简略且易操作。可是关于多维数组,相同的操作要杂乱得多”,形成这一问题的本源在于Matlab与C++对多维数组元素的存储办法不同。而在本项目开发进程中逃避了这个杂乱的进程,转而运用Matlab强壮的数组处理功用将其处理。Matlab完善的图形处理功用是其被科研人员所推重的原因之一,但因其图形具有独立的窗口,严重影响了全体界面漂亮和用户交互体会,所以Matlab图形嵌入是混合编程中不行逃避的问题。对此将经过实例介绍两种图形嵌入办法并剖析阐明其优缺陷和相关细节。

本文示例均在Matlab R2008a和VC 6.0渠道下完结,且经过调试能够正常运转。

1 Excel文件读取办法

VC渠道下的Excel文件读取办法杂乱难明,但假如运用Matlab与VC的混合编程办法编写将愈加简洁,并且具有较强的可扩展性。下面代码具体讲解了该进程。

(1)在Matlab渠道下树立CExcelRead.m文件,代码如下:

function [output,row,col] = CExcelRead(filePath)

//filePath包括了指定文件的途径和文件名,由VC渠道函数GetPathName()获取

[typ, desc] = xlsfinfo(filePath);

//xlsfinfo()可获取指定Excel文件中各个sheet作业区的称号,回来值存入名为desc的cell数组中

sheet1 = cell2mat(desc(1));

//默许翻开”sheet1”(称号恣意),并将其转化为字符串

output = xlsread(filePath,sheet1);

//回来该Excel文件中的数据,回来值存入output数组中

[row,col] = size(output);

//获取录入数据的队伍值,回来到VC渠道以供其复制指定内存大小的数据

output = reshape(output,row*col,1);

//将该二维数组转化为一维。这是第二部分二维数组处理的榜首步

保存文件后,运用deploytool东西将其制造成名为FileOpen的COM(封装MCR),注册该控件并将相应的文件复制到MFC的工程中,关于根底操作此处不再赘述。

(2)在VC渠道下创立名为PCA的根据对话框的MFC工程,添加一翻开文件的按钮控件,ID为ID_FILE_OPEN。篇幅所限只给出部分中心代码,首要在Dlg类中添加3个私有成员变量用以保存Matlab读取的数据及队伍值,即:

double *m_originData; long m_row, m_col;

在呼应函数中添加如下代码

CFileDialog fileDlg(TRUE);

fileDlg.m_ofn.lpstrTitle=请挑选你的excel数据;

fileDlg.m_ofn.lpstrFilter=Text Files(*.xls)*.xlsAll Files(*.*)*.*;

if(IDOK==fileDlg.DoModal() {

CString fileName; IFileOpenclass *pfile;

VARIANT filePath,output,rowOutput,colOutput;

//m文件的输入参数

fileName = fileDlg.GetPathName();

//获取文件途径并存于fileName中

CoInitialize(NULL); //COM初始化

HRESULT hr = CoCreateInstance(CLSID_FileOpenclass,NULL,CLSCTX_ALL,IID_IFileOpenclass,(void**)pfile);

//新建COM实例

VariantInit(filePath); //VARIANT数据初始化

filePath.vt = VT_BSTR; //指定filePath变量类型

//将fileName中保存的指定文件途径名保存至filePath参数中

filePath.bstrVal = fileName.AllocSysString();

pfile->CExcelRead(3,output,rowOutput, colOutput,filePath);

m_row=(long) rowOutput.dblVal;

//取出队伍值及录入数据

m_col = (long) colOutput.dblVal;

m_originData = (double *)malloc(sizeof(double)*m_row*m_

col); memcpy(m_originData,output.parray->pvData,m_row*m_

col*sizeof(double));

//将matlab读入数据保存到m_originData供后边程序运用

}

上述C++代码中省掉了反常处理和相关的内存、COM开释代码,因为代码比较简略所以不做进一步解析。请留意,下面将省掉COM初始化及实例化等相同代码。

(3) 需求要点阐明的是该办法的扩展性。一般Excel文件中保存多个作业区,有时用户或许需求翻开同一Excel文件中不同作业区中的数据,惯例办法完结过于杂乱,但关于本文介绍的办法能够经过修正添加几条句子即可完结。首要,新建一个m文件用来处理作业区的挑选,代码如下:

function [sheet,col] = CSheetSelected(filePath)

[typ, sheet] = xlsfinfo(filePath);

[row,col] = size(sheet);

因为回来值是一个cell数组,所以VC渠道要运用CStringArray数据结构保存回来值,并显现各作业区称号供用户挑选。然后,经过人机交互将用户挑选的作业区参数保存并传递至CExcelRead.m,经过在CExcelRead.m添加一个作业区挑选参数,并对代码稍作修正即可。

2 二维数组参数的传递与输出[2]

下面以主成分剖析为例介绍根据COM的Matlab与VC混合编程中二维数组参数处理。

(1) 主成分剖析pcamat.m代码如下:

function [eigenvector,eigenvalue] = pcamat(oriData,row,column)

//在Excel读入时现已完结了二维数组输出的关键步骤,即输出时将二维数组转化为一维数组。但在VC渠道接纳还原为二维时要留意,Matlab数组存储办法是按列存储,而VC渠道下数组是按行存储,所以转化时0~row-1为榜首列,row~2*row-1为第二列,以此类推。本文输入参数oriData是一维数组,所以要将其还原为二维数组使Matlab程序能够正常运转,即下一行代码所示。

oriData = reshape(oriData,row,column);

dataSTD=std(oriData,0,1); dataMean = mean(oriData);

dataSR = (oriData-dataMean(ones(row,1),:))./dataSTD(ones(row,1),:);

[eigenvector,newdata,eigenvalue,Exa]=princomp(dataSR);

//第三行至此处均为主成分剖析内容

eigenvector = reshape(eigenvector,column*column,1);

//与Excel文件读取时相似,将二维输出转化为一维数组进行输出

(2) 保存后,封装打包为COM组件,并完结注册等相关操作。在PCA工程对话框上添加一个名为PCATest的按钮控件,中心代码如下:

VARIANT oriData,row,column,eigVector,eigValue;

VariantInit(oriData); //参数初始化

oriData.vt = VT_R8|VT_ARRAY;

//界说SAFEARRAY类型的一维数组

SAFEARRAYBOUND rgsadound[1];

rgsadound[0].lLbound = 0;

rgsadound[0].cElements = m_row*m_col;

oriData.parray = SafeArrayCreate(VT_R8,1,rgsadound);

oriData.parray->pvData = m_originData;

//完结相关设置后,将榜首步读入的数据录入到oriData中,即赋给pcamat的oriData。到此完结了二维数组的传递

row.vt = VT_I4; col.vt = VT_I4;

row.lVal = m_row; col.lVal = m_col;

pca->pcamat(2,eigVector,eigValue,oriData,row,col);

memcpy(result, eigVector.parray->pvData,m_col*m_col*

sizeof(double));

综上,二维数组参数处理便是运用reshape()函数对输入输出数据维数进行变换来完结操作。

3 Matlab图画嵌入VC界面[3]

3.1 根据CWnd类的图画嵌入

在Windows操作体系下,一切应用程序的窗口都是根据MFC中的CWnd类。所以能够经过调用该类或其派生类中的办法完结图画嵌入。根本思想:在Matlab渠道下用COM封装发生图形窗口的程序;在VC渠道获取Figure窗口的句柄,将Figure窗口设为VC程序的子窗口;(3)将Figure窗口移动到指定显现方位。

程序完结如下:

(1)将原pcamat.m进行修正,添加生成图画的相关代码

function [eigenvector,eigenvalue] = pcamat(oriData,row,column,picName)

//添加picName参数,VC渠道下hFig将经过该称号获取生成图画的句柄

figure(NumberTitle,Off,MenuBar,None,ToolBar,Figure,Name,picName,Units,Points);

//图画参数预设,保存东西栏。运用Matlab供给的东西栏的一切功用是运用该办法的最大长处

percent = 100*eigenvalue /sum(eigenvalue);

//核算贡献率

pareto(percent); //画图

xlabel(主成分);

ylabel(方差占的比重(%));

(2)封装打包成名为figure的COM组件,并完结注册等相关操作。因为修正后的m文件运转成果包括输出成果和图画两部分,所以下面有关图画处理的代码依然在PCATest控件的呼应函数中。

CString WNDName = Demo; //自界说窗口称号

Ifigureclass *pic;

VARIANT oriData, row, col, picName,eigVector, eigValue; VariantInit(picName);

……

picName.vt = VT_BSTR; //将自界说窗口称号赋予

Matlab生成图画

picName.bstrVal = WNDName.AllocSysString();

HWND hFig; int timer = 50;

//用死循环保证能够获取到图画句柄,留意此处有必要运用sleep(),给予体系满意的呼应时刻

while(1){

pic->pcamat(2,eigVector,eigValue,oriData,row,col,

picName);

Sleep(timer);

hFig = ::FindWindow(NULL,FigName);

if(hFig != NULL){

break;

}

timer += 10;

pic->Release();

}

long lStyle = ::GetWindowLong(hFig,GWL_STYLE); //设置Figure窗口款式。

//留意SetWindowLong()和SetWindowPos()先后顺序,详见MSDN

::SetWindowLong(hFig,GWL_STYLE,lStyle(~WS_CAPTION)(~WS_THICKFRAME))

::SetWindowPos(hFig,NULL,0,0,0,0,SWP_NOMOVE|SWP_

NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_

FRAMECHANGED);CRect PlotRec;

CWnd *PlotArea = GetDlgItem(IDC_STATIC_FIGURE); //设置图画显现区域

PlotArea->GetWindowRect(PlotRec);

long Width = PlotRec.right – PlotRec.left;

long Height = PlotRec.bottom – PlotRec.top;

::SetParent(hFig,PlotArea->GetSafeHwnd());

//设置图画的父窗口

::SetWindowPos(hFig,NULL,0,0,Width,Height,SWP_NOZORDER|SWP_NOACTIVATE);

该办法的缺陷是,在图画生成时会有闪耀现象。而长处是前面说到的能够持续运用Matlab供给的东西栏。鉴于该缺陷影响全体漂亮,所以引进下面第二种办法。

3.2根据Bitmap类的图画嵌入

经过Bitmap类将Matlab生成的.bmp文件加载到VC工程中,运用Bitmap类中的成员函数对图画进行处理。因为相关函数能够经过协助手册获取,所以此处不再给出相应代码,运转成果如图2所示。该办法避免了办法一生成图画时的闪耀现象,可是BMP图画显现作用较差并且无法运用Matlab供给的东西菜单,这是其不足之处。

运用COM组件进行混合编程时,往往习惯于在VC渠道下考虑所遇到的问题,可是这样不只使得问题或许变得杂乱化,或得不到妥善处理,并且也违反了“混合”的初衷。二维数组参数处理便是一个很好的例子。其次,充分运用Matlab特性能够使得程序具有杰出的扩展性和稳定性,对Excel文件读取办法进行的扩展,显着使软件愈加人性化。关于图画嵌入问题,尽管文中提出的两种嵌入办法能够满意根本需求,可是依然存在一些瑕疵,还需求进一步研讨。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/news/dongtai/287175.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部