www.gusucode.com > VC++漂亮窗体控件及菜单类的示例-源码程序 > VC++漂亮窗体控件及菜单类的示例-源码程序/code/VC++菜单类的演示/Leach.cpp
//Download by http://www.NewXing.com // Leach.cpp: implementation of the CLeach class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "cardio.h" #include "Leach.h" #include "math.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CLeach::CLeach() { Init_AllFilters_Parameter(); //初始化所有滤波器的参数 } CLeach::~CLeach() { } /*-*-*-*-*-*-*-*-*第一类零阶修正贝塞尔函数*-*-*-*-*-*-*-*-*-*/ /*-*-*--*-*-*-*-*-x即为kaiser窗的beta参数*-*-*-*-*-*-*-*-*-*-*/ double CLeach::besse10(double x) { int i; double d,y,d2,sum; y=x/2.0; d=1.0; sum=1.0; for(i=1;i<25;i++) { d=d*y/i; d2=d*d; sum=sum+d2; if(d2<sum*(1.0e-8)) break; } return(sum); } /*-*-*-*-*-*-*-*-*-*单点kaiser窗值*-*-*-*-*-*-*-*-*-*-*/ /*---------------i为kaiser窗的第几个值----------------*/ /*-----------------n为kaiser窗的阶数------------------*/ /*-*-*-*-*-*-*-*-*-*beta为kaiser窗的参数*-*-*-*-*-*-*-*/ double CLeach::kaiser(int i, int n, double beta) { double a,w,a2,b1,b2,beta1; b1=besse10(beta); a=2.0*i/(double)(n-1)-1.0; a2=a*a; beta1=beta*sqrt(1.0-a2); b2=besse10(beta1); w=b2/b1; return(w); } /*-*-*-*-*-*-*-*-*-*-*-*低通输出*-*-*-*-*-*-*-*-*--*-*-*/ // 参数说明 // n代表低通截止频率的序号 // x----- 采集的数据 // k----- 第几个通道 double CLeach::lowpass(int n,double x,int k) { // return 0; double sum=0; static double yl[64][Num_filter+1]; double tmp[Num_filter]; CopyMemory(tmp,&yl[k][1],sizeof(tmp)); CopyMemory(yl[k],tmp,sizeof(tmp)); yl[k][Num_filter]=x; for(int j=0;j<=Num_filter;j++) { sum=sum+m_coefficient[n][j]*yl[k][Num_filter-j]; } return sum; } /*-*-*-*-*-*-*-*-*-*高通滤波*-*-*-*-*-*-*-*-*-*-*/ // 参数说明 // n----- 高通截止频率的序号 // x----- 采集的数据 // k----- 第几个通道 double CLeach::highpass(int n,double x,int k) { // return 0; double sum1,sum; sum1=sum=1; static double in_h[64][2],out_h[64]; in_h[k][0]=in_h[k][1]; in_h[k][1]=x; sum1=in_h[k][1]-in_h[k][0]+(1-wp[n])*out_h[k]; sum=sum1/(1+wp[n]); out_h[k]=sum; double tmp; tmp=out_h[k]; if(tmp<0) tmp*=-1.0; if(tmp<1e-6) out_h[k]=0; return sum; } /*-*-*-*-*-*-*-*-*ECG 自适应50Hz滤波*-*-*-*-*-*-*-*-*/ double CLeach::notch_ECG(double x,int k) { static double in_n[64][3],out_n[64][2]; double sum,sum1,sum2; for(int i=0;i<2;i++) { in_n[k][i]=in_n[k][i+1]; } in_n[k][2]=x; sum1=b_ecg[0]*in_n[k][2]+b_ecg[1]*in_n[k][1]+b_ecg[2]*in_n[k][0]; sum2=a_ecg[1]*out_n[k][1]+a_ecg[2]*out_n[k][0]; sum=(sum1-sum2)/a_ecg[0]; out_n[k][0]=out_n[k][1]; out_n[k][1]=sum; double tmp; tmp=out_n[k][1]; if(tmp<0) tmp*=-1.0; if(tmp<1e-6) out_n[k][1]=0; return sum; } /*-*-*-*-*-*-*-*-*BIO 自适应50Hz滤波*-*-*-*-*-*-*-*-*/ double CLeach::notch_BIO(double x,int k) { static double in_n[64][3],out_n[64][2]; double sum,sum1,sum2; for(int i=0;i<2;i++) { in_n[k][i]=in_n[k][i+1]; } in_n[k][2]=x; sum1=b_bio[0]*in_n[k][2]+b_bio[1]*in_n[k][1]+b_bio[2]*in_n[k][0]; sum2=a_bio[1]*out_n[k][1]+a_bio[2]*out_n[k][0]; sum=(sum1-sum2)/a_bio[0]; out_n[k][0]=out_n[k][1]; out_n[k][1]=sum; double tmp; tmp=abs(out_n[k][1]*1e+10); if(tmp<1e-10) out_n[k][1]=0; return sum; } /********************压力输出(FIR)*******************/ // 参数说明 // n----- 压力低通截止频率值的序号 // x----- 采集的数据 // k----- 第几个通道 double CLeach::Bp(int n,double x,int k) { // return 0; double sum=0; static double yb[64][Num_bp+1]; double tmp[Num_bp]; CopyMemory(tmp,&yb[k][1],sizeof(tmp)); CopyMemory(yb[k],tmp,sizeof(tmp)); yb[k][Num_bp]=x; for(int j=0;j<=Num_bp;j++) { sum=sum+bp_coefficient[n][j]*yb[k][Num_bp-j]; } return sum; } /*-*-*-*-*-*-*-*-*-*-*-*心率带通输出*-*-*-*-*-*-*-*-*--*-*-*/ // 参数说明 // x----- 采集的数据 // k----- 第几个通道 double CLeach::heart_out(double x,int k) { double sum=0; static double y[2][Num_heart+1]; double tmp[Num_heart]; CopyMemory(tmp,&y[k][1],sizeof(tmp)); CopyMemory(y[k],tmp,sizeof(tmp)); y[k][Num_heart]=x; for(int j=0;j<=Num_heart;j++) { sum=sum+heart_coefficient[j]*y[k][Num_heart-j]; } return sum; } /*-*-*-*-*-*-*-*-*-*-*-*去除肌电干扰37Hz低通滤波输出*-*-*-*-*-*-*-*-*--*-*-*/ double CLeach::skin_lp(double x,int k) { double sum1,sum; static double in[64][2],out[64]; in[k][0]=in[k][1]; in[k][1]=x; sum1=b_skin[0]*in[k][1]+b_skin[1]*in[k][0]-a_skin[1]*out[k]; sum=sum1/a_skin[0]; out[k]=sum; return sum; } void CLeach::Init_Lowpass_Parameter() { int Frq_lp[7]={100,150,200,400,600,800,1200}; //低通截止频率 /*-*-*-*-*-*-*低通滤波*-*-*-*-*-*-*/ double beta[7]={2.5,3.4,4.3,6,6,6,6}; //低通窗函数参数 for(int j=0;j<7;j++) { double wc=2*PI*(Frq_lp[j]+95)/Frq_Sam; //wc为相对角频率 double hd[Num_filter+1]={0}; //保存不加窗函数的滤波器系数 double wd[Num_filter+1]={0}; //保存kaiser窗函数系数 for(int i=0;i<=Num_filter;i++) { if(i==Num_filter/2) { hd[i]=wc/PI; } else { hd[i]=sin((i-Num_filter/2)*wc)/(PI*(i-Num_filter/2)); } wd[i]=kaiser(i,Num_filter+1,beta[j]); m_coefficient[j][i]=hd[i]*wd[i]; //低通滤波器系数 } } } void CLeach::Init_Highpass_Parameter() { double Frq_hp[13]={0.05,0.5,1,10,20,30,40,50,60,70,80,90,100}; //高通截止频率 /*-*-*-*-*-*-*-*高通滤波*-*-*-*-*-*-*-*-*/ for(int k=0;k<13;k++) { wp[k]=tan(PI*Frq_hp[k]/Frq_Sam); //高通滤波所需系数 } } void CLeach::Init_Bp_Lowpass_parameter() { double Frq_bp[3]={20,30,40}; //压力低通截止频率 /*-*-*-*-*-*-*BP低通(FIR)*-*-*-*-*-*-*-*-*/ // double beta_bp=5; //压力低通窗函数参数 double beta_bp[3]={2.05,3,4}; //压力低通窗函数参数 for (int j=0;j<3;j++) { double wc1=2*PI*(Frq_bp[j]+15)/Frq_Sam; //wc1为相对角频率 double hd1[Num_bp+1]={0}; //保存不加窗函数的滤波器系数 double wd1[Num_bp+1]={0}; //保存kaiser窗函数系数 for(int i=0;i<=Num_bp;i++) { if(i==Num_bp/2) { hd1[i]=wc1/PI; } else { hd1[i]=sin((i-Num_bp/2)*wc1)/(PI*(i-Num_bp/2)); } wd1[i]=kaiser(i,Num_bp+1,beta_bp[j]); bp_coefficient[j][i]=hd1[i]*wd1[i]; //低通滤波器系数 } } } void CLeach::Init_ECG_50Hz_Parameter() { /*-*-*-*-*-*-*ECG 50Hz滤波滤波器系数*-*-*-*-*-*-*-*/ double BW_ECG=2; //陷波带宽,单位为Hz double U_ECG=BW_ECG*PI/Frq_Sam; double w_ECG=2*PI*50/Frq_Sam; double rez_ECG=cos(w_ECG); b_ecg[0]=1; //b_ecg[] 滤波器分子系数 b_ecg[1]=-2*rez_ECG; b_ecg[2]=1; a_ecg[0]=1; //a_ecg[]滤波器分母系数 a_ecg[1]=-2*rez_ECG*(1-U_ECG); a_ecg[2]=1-U_ECG*2; } void CLeach::Init_BIO_50Hz_Parameter() { /*-*-*-*-*-*-*BIO 50Hz滤波滤波器系数*-*-*-*-*-*-*-*/ double BW_BIO=1; //陷波带宽,单位为Hz double U_BIO=BW_BIO*PI/Frq_Sam; double w_BIO=2*PI*50/Frq_Sam; double rez_BIO=cos(w_BIO); b_bio[0]=1; //b_bio[] 滤波器分子系数 b_bio[1]=-2*rez_BIO; b_bio[2]=1; a_bio[0]=1; //a_bio[]滤波器分母系数 a_bio[1]=-2*rez_BIO*(1-U_BIO); a_bio[2]=1-U_BIO*2; } void CLeach::Init_SkinNoise_Parameter() { /*-*-*-*-*-*-*-*去除肌电干扰37Hz低通滤波系数*-*-*-*-*-*-*-*/ double Frq_skin=36; double w_skin=tan(PI*Frq_skin/Frq_Sam); b_skin[0]=b_skin[1]=w_skin; a_skin[0]=1+w_skin; a_skin[1]=w_skin-1; } void CLeach::Init_AllFilters_Parameter() //初始化所有滤波器的参数 { Init_Lowpass_Parameter(); //初始化低通滤波器的参数 Init_Highpass_Parameter(); //初始化高通滤波器的参数 Init_Bp_Lowpass_parameter();//初始化压力低通滤波器的参数 Init_ECG_50Hz_Parameter(); //初始化ECG 50Hz滤波器的参数 Init_BIO_50Hz_Parameter(); //初始化BIO 50Hz滤波器的参数 Init_SkinNoise_Parameter();//初始化去除肌电干扰滤波器的参数 Init_R_CheckUp_Parameter(); //初始化R波检测滤波器的参数 Init_50Hz_BandPass(); } void CLeach::Init_R_CheckUp_Parameter() { /*-*-*-*-*-*-*计算心率滤波器系数*-*-*-*-*-*-*-*/ double beta_heart=6; //心率带通窗函数参数 double wl=2*PI*5/Frq_Heart; //wh为相对角频率 double wh=2*PI*33/Frq_Heart; //wl为相对角频率 double hd_heart[Num_heart+1]={0}; //保存不加窗函数的滤波器系数 double wd_heart[Num_heart+1]={0}; //保存kaiser窗函数系数 for(int i=0;i<=Num_heart;i++) { if(i==Num_heart/2) { hd_heart[i]=(wh-wl)/PI; } else { hd_heart[i]=sin((i-Num_heart/2)*wh)/(PI*(i-Num_heart/2)) -sin((i-Num_heart/2)*wl)/(PI*(i-Num_heart/2)); } wd_heart[i]=kaiser(i,Num_heart+1,beta_heart); heart_coefficient[i]=hd_heart[i]*wd_heart[i]; //心率带通滤波器系数 } } double CLeach::Operate_heart_out(double x, int k) { double sum=0; static double yy[2][Num_heart+1]; double tmp[Num_heart]; CopyMemory(tmp,&yy[k][1],sizeof(tmp)); CopyMemory(yy[k],tmp,sizeof(tmp)); yy[k][Num_heart]=x; for(int j=0;j<=Num_heart;j++) { sum=sum+heart_coefficient[j]*yy[k][Num_heart-j]; } return sum; } void CLeach::Init_50Hz_BandPass() { /*-*-*-*-*-*-*50Hz带通滤波器系数*-*-*-*-*-*-*-*/ double BW1=10; //带通带宽,单位为Hz double U1=BW1*PI/Frq_Sam; double w1=2*PI*50/Frq_Sam; double rez1=cos(w1); a_50_bp[0]=1; //a1[]滤波器分母系数 a_50_bp[1]=-2*rez1*(1-U1); a_50_bp[2]=1-U1*2; b_50_bp[0]=0; //b1[] 滤波器分子系数 b_50_bp[1]=2*rez1*U1; b_50_bp[2]=-2*U1; } double CLeach::V_BandPass(double x, int k) { static double in_n[64][3],out_n[64][2]; double sum,sum1,sum2; for(int i=0;i<2;i++) { in_n[k][i]=in_n[k][i+1]; } in_n[k][2]=x; sum1=b_50_bp[0]*in_n[k][2]+b_50_bp[1]*in_n[k][1]+b_50_bp[2]*in_n[k][0]; sum2=a_50_bp[1]*out_n[k][1]+a_50_bp[2]*out_n[k][0]; sum=(sum1-sum2)/a_50_bp[0]; out_n[k][0]=out_n[k][1]; out_n[k][1]=sum; return sum; }