(matlab7.0与vc++6.0混合编程(win7系统),使用com组件的方式实现vc++6.0调用matlab的小波去噪工具箱函数)

最重要的须知!!!

1.matlab一定是安装matlab7.0版本。
2.vc++6.0的位置一定是安装在C:\Program Files\Microsoft Visual Studio位置。

不要尝试其他matlab版本,我已经花了整整近四天时间安装过
matlab2020b,matlab2016b,与matlab2015b与vc++6.0混合编程,均已失败告终,我装软件都装吐了,因为就拿matlab2020b来讲,压缩包,解压,及安装下来至少40G,你去细品吧(下载,卸载,安装)!!因为我是第一次用matlab与vc++6.0混合编程,如果你是大牛,期待你能带给我们惊喜。一般人的话做个阿甘吧,乖,听话!!!

安装matlab7.0,vc++6.0

安装matlab7.0就在网上随便找7.0版本下载,安装过程找度娘搜一下就有了,vc++6.0的安装就不说了。matlab7.0安装好后可能打不开,可能是兼容性问题,请百度解决方案哟,加油你可以的!!

配置环境变量

本来有一篇博客有写详尽的配置方案的,但是他们今天居然在整改,先将网址粘在这里,大家一定去看,很详细,我能成功真的多亏了这篇博客,我不是打广告啊,谁写的我也不认识, 但是又详细又好真的是爱了爱了。
https://www.cnblogs.com/cmt/p/14553189.html
大家不要去了就不回来了,过程基本上是一样的,但是后面的小波去噪部分都是我自己搞出来的。
配置环境变量
1.控制面板\系统和安全\系统\高级系统设置\环境变量\系统变量\PATH
下加上D:\matlab7.0\extern\include;D:\matlab7.0\extern\lib\win32\microsoft\msvc70;D:\matlab7.0\bin\win32;这三个路径,其中D:\matlab7.0是我电脑matlab7.0的安装路径。
2.控制面板\系统和安全\系统\高级系统设置\环境变量\系统变量\编辑
变量名:matlab
变量值:D:\matlab7.0(你的matlab7.0路径)
不要忘记点确定。
听说环境变量配置过后要关机重启才能生效,不管是不是真的我每次都重启。

让matlab7.0连上vc++6.0的编译器

1.在matlab命令行输入mbuild -setup,回车出现下图
在这里插入图片描述y 回车则出现下图
在这里插入图片描述选2就是你的vc++6.0路径,回车出现下图
在这里插入图片描述问你是不是确定你的选择,y回车就可以,出现下图就可以了
在这里插入图片描述然后还是在命令行输入mex -setup,回车出现下图
在这里插入图片描述还是y回车,出现下图
在这里插入图片描述选3,就是你的vc++6.0,回车出现下图
在这里插入图片描述还是y回车,出现下图就成功了
在这里插入图片描述
以上都做好后就可以生成com组件了

生成com组件

在命令行输入comtool回车弹出下面这个框
在这里插入图片描述File\New Project弹出下面这个框
在这里插入图片描述给你的com组件取一个帅气的英文名(在component name下面),点击Classes的空白处,会自动生成一个类名,Project directory是生成的com组件的位置,这个需要记忆以下,待会会用,我的路径是D:\matlab7.0\work\plot,另外Compiler option下面两个都勾选,有的只有一个,就勾选一个,点OK就行,plot是我的com组件名,plotclass是我的类名,点开plotclass,选中M-files,如下图所示。
在这里插入图片描述然后Project\Add Files选择你想在vc++6.0里面调用的matlab函数的路径,这里我们调用的是matlab中的wden.m函数,把这个函数的路径添加进来,如下图。
在这里插入图片描述

然后点击Build\Com Object就会开始生成com组件,出现下图就成功了。
在这里插入图片描述
到现在基本上就没有matlab什么事了。

对于wden.m函数有非常重要的事情交代

wden.m函数是matlab的工具箱函数,一共有7个输入参数,3个返回值,在matlab中调用时也可以用6个输入参数调用,因为wden.m函数内部有判断输入参数个数的代码,可根据输入参数的不同分别执行不同的代码。这么多字,看到这里是不是累了,但真的很重要,耐心看下去。这一共10各参数,生成com组件的接口是10个variant的结构体类型变量,这是一个超级超级复杂的结构体,赋值和提取值都很复杂,如果不改wden.m函数的接口就没办法完成我的功能,我把wden函数改成的1个输入参数,1个输出参数,输入参数是待滤波的数据,输出参数是滤波后的参数。这样我再vc++6.0中就只需要操作2个参数了。下面是我修改后的wden.m函数,名字是wden1.m。

function [xd] = wden1(in1)
%WDEN Automatic 1-D de-noising using wavelets.
%   WDEN performs an automatic de-noising process of a 1-D
%   signal using wavelets.
%
%   [XD,CXD,LXD] = WDEN(X,TPTR,SORH,SCAL,N,'wname') returns 
%   a de-noised version XD of input signal X obtained by 
%   thresholding the wavelet coefficients. 
%   Additional output arguments [CXD,LXD] are the wavelet 
%   decomposition structure of de-noised signal XD.
%
%   TPTR string contains threshold selection rule:
%   'rigrsure' use principle of Stein's Unbiased Risk.
%   'heursure' is an heuristic variant of the first option.
%   'sqtwolog' for universal threshold sqrt(2*log(.)).
%   'minimaxi' for minimax thresholding.
%       (see THSELECT for more details).
%   SORH ('s' or 'h') is for soft or hard thresholding
%       (see WTHRESH for more details).
%   SCAL defines multiplicative threshold rescaling:
%     'one' for no rescaling.
%     'sln' for rescaling using a single estimation 
%       of level noise based on first level coefficients.
%     'mln' for rescaling done using level dependent
%       estimation of level noise.
%   Wavelet decomposition is performed at level N and 'wname'
%   is a string containing the name of desired orthogonal
%   wavelet.
%
%   [XD,CXD,LXD] = WDEN(C,L,TPTR,SORH,SCAL,N,'wname') returns 
%   same output arguments, using the same options as above, but 
%   obtained directly from the input wavelet decomposition 
%   structure [C,L] of the signal to be de-noised, at level N
%   and using 'wname' orthogonal wavelet.
%
%   See also THSELECT, WAVEDEC, WDENCMP, WFILTERS, WTHRESH.

%   M. Misiti, Y. Misiti, G. Oppenheim, J.M. Poggi 12-Mar-96.
%   Last Revision: 14-May-2003.
%   Copyright 1995-2004 The MathWorks, Inc.
% $Revision: 1.10.4.2 $

% Check arguments.
%nbIn = nargin;
%switch nbIn
 % case {0,1,2,3,4,5}  , error('Not enough input arguments.');
 % case 6 ,
      x = in1; tptr = 'minimaxi'; sorh = 's'; 
      scal = 'sln'; n = 4; w = 'sym3';
 % case 7 ,
 %     c = in1; l = in2; tptr = in3; 
 %    sorh = in4; scal = in5; n = in6; w = in7;
%end
if errargt(mfilename,tptr,'str'), error('*'), end
if errargt(mfilename,sorh,'str'), error('*'), end
if errargt(mfilename,scal,'str'), error('*'), end
if errargt(mfilename,n,'int'), error('*'), end
if errargt(mfilename,w,'str'), error('*'), end

%if nbIn==6
    % Wavelet decomposition of x.
    [c,l] = wavedec(x,n,w);
%end

% Threshold rescaling coefficients.
switch scal
  case 'one' , s = ones(1,n);
  case 'sln' , s = ones(1,n)*wnoisest(c,l,1);
  case 'mln' , s = wnoisest(c,l,1:n);
  otherwise  , error('Invalid argument value.')
end

% Wavelet coefficients thresholding.
first = cumsum(l)+1;
first = first(end-2:-1:1);
ld   = l(end-1:-1:2);
last = first+ld-1;
cxd = c;
lxd = l;
for k = 1:n
    flk = first(k):last(k);
    if tptr=='sqtwolog' | tptr=='minimaxi'
        thr = thselect(c,tptr);
    else
        if s(k) < sqrt(eps) * max(c(flk))
            thr = 0;
        else
            thr = thselect(c(flk)/s(k),tptr);
        end
    end                                     % threshold.
    thr      = thr * s(k);                  % rescaled threshold.
    cxd(flk) = wthresh(c(flk),sorh,thr);    % thresholding or shrinking.
end

% Wavelet reconstruction of xd.
xd = waverec(cxd,lxd,w); 


vc++6.0调用com组件

一般的调用方法
还是根据上面提到的那篇博客完成就可以。大约3.25号整改完成后就可以看了,如果不能看我再加更这一部分的内容。

调用小波去噪函数

怎么把待滤波的一维数组转换成可以调用的variant类型,并从variant类型中提取滤波后的一维数组,这一段非常重要,一维数组的类型是double类型的。

void DISPLAYTEM::OnStart() 
{
	// TODO: Add your control notification handler code here
			plot.CreateDispatch(CLSID_waveletclass,NULL); //创立接口
COleDispatchDriver(); //连接(此句可以不写)
}

void DISPLAYTEM::OnPlot() 
{
	// TODO: Add your control notification handler code here
	 const int N=2960; //数组大小
  double a[N]; //数组定义
  
// 赋值
  for (int i=0; i<N; i++)
  {
    a[i]=T[i+1];
  }
  //char IN1[10]={'m','i','n','i','m','a','x','i'};
  //char IN2[10]={'s'};
  //char IN3[10]={'s','l','n'};
  //long IN4 = 4;
  //char IN5[10]={'s','y','m','3'};
//任意变量
  VARIANT x;
  VARIANT xd;


  VariantInit(&x); //初始化
  VariantInit(&xd); //初始化


  x.vt=VT_ARRAY|VT_R8; //类型(数组,双精度型)
  xd.vt=VT_ARRAY|VT_R8; //类型(数组,双精度型)

  SAFEARRAYBOUND rgsabound[1]; 
  rgsabound[0].cElements=N; //数组所含元素数
  rgsabound[0].lLbound=0;   //数组上界

  //创立数组
  x.parray=SafeArrayCreate(VT_R8,1,rgsabound); //创立一维安全数组
  xd.parray=SafeArrayCreate(VT_R8,1,rgsabound); //创立一维安全数组


  //锁定数组
  SafeArrayLock(x.parray);
  SafeArrayLock(xd.parray);

 
  //数组传递数据
  x.parray->pvData=a;

  //调用方法

  plot.wden1(1,&xd,x); 
//把variant的double类型数组给提取处来
long dim = SafeArrayGetDim(xd.parray);
long ubound;
long lbound;
	SafeArrayGetUBound(xd.parray,dim,&ubound);
	SafeArrayGetLBound(xd.parray,dim,&lbound);
double *buf;
	SafeArrayAccessData(xd.parray,(void**)&buf);
for(int o=lbound;o<ubound;o++)
{
	Wavelet_T[o]=buf[o];
}

x里有待滤波数组(带滤波数组开始在a数组里,是我需要处理的数据T数组中的一部分),xd里有滤波后数组(滤波后的数组存在Wavelet_T数组中),具体怎么调用的参见代码,然后我把滤波前后的数据通过mfc绘制成图表显示出来了,我滤波的是温度数据,滤波后的波动范围明显小了,如下图!
滤波前滤波后

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值