利用周期序列的相关性,对被随机信号干扰的信号进行处理,提取其中有用的周期性信号
基本算法思路:
对于如下信号 y(n)=x(n)+w(n)
其中x(n)是一未知周期为N的周期信号,w(n)为加性随机干扰信号。
则y(n)为所观察到的被随机信号干扰的信号
程序设计的任务是:把包含有随机干扰的信号y(n)中提出信号x(n)
处理方法是利用周期信号的相关性:
对y(n)观察它的M个样本,比如说n∈[0,M--1],其中M>N,假设在n<0和n>M时y(n)=0,则y(n)的自相关序列为:
即可以得到:
由于随着l 趋向于M,并且样本点M是有限的,以至于乘积x(n)*x(n-1)中很多为零
所以,对于l>M/2,就可以不计算
M太小,相关性太大,应该很难去除干净,太多了,也就把些不相关的都加进去了,所以大了效果不好,所以处理的个数M取值(64-256)
而信号x(n)和加性随机干扰之间的互相关r xw(l )和r wx(l )相对较小,很快衰减到零,所以在l >0时,只有r xx(l)有较大的峰值,这个特点使我们可以从噪声和干扰w(n)中检测出周期信号x(n)的存在以及它的周期是多少
设计特色:把每一部分要实现的功能都模块化了,整个程序分为正弦函数生成函数,显示子函数,画坐标子函数,互相关子函数,对程序的功能扩展和分析有很大的帮助,画出了正弦曲线的坐标可以很清楚的看到,利用周期序列的相关性,对被随机信号干扰的信号进行处理,提取其中有用的周期性信号的结果
有待扩展的功能是:通过频域分析对信号的频域分析得出它的频域特性
源程序:
#include "stdio.h"
#include "graphics.h"
#include "math.h"
#include "stdlib.h"
#define PI 3.1415926
#define N 1024
float signal [N];
float signal_out[N];
void createsignal(); /*正弦函数生成函数*/
void displaysignal(int x0,int y0,float ratio,unsigned char display); /*显示子函数*/
void zuobiao(int Ax0,int Ay0,int Ax,int Lx0,int Ly0,int Ly,int xi,int yj); /*画坐标子函数*/
void xxcov(unsigned int Num); /*互相关函数*/
void main()
{int driver=VGA,mode=VGAHI;
initgraph(&driver,&mode,"c:\tc");
setbkcolor(1); /*设置背景颜色*/
getch();
setcolor(5); /*调用画坐标子函数*/
zuobiao(12,100,500,247,30,180,10,10);
setcolor(5);
zuobiao(12,300,500,247,230,400,10,10);
getch();
createsignal(); /*调用正弦曲线子函数*/
setcolor(2);
displaysignal(10,100,1,0);
getch();
xxcov(500); /*调用互相关子函数*/
setcolor(2);
displaysignal(10,300,1,1);
getch();
createsignal();
setcolor(2);
displaysignal(2,300,1,0);
/*getch();*/
closegraph();
}
void createsignal()
{float a=50,f=100,fi=10*PI/180;
float ts=1.0/4000;
int k,i;
for(k=0;k<N;k++)
{signal[k]=0;
{signal[k]+=a*sin(2*PI*f*k*ts+fi);
signal[k]+=rand()*10.0/RAND_MAX-5;
}
}
}
void displaysignal(int x0,int y0,float ratio,unsigned char display)
{int i,x,y;
for(i=0;i<240;i++)
{x=x0+2*i;
switch(display)
{
case 0:y=y0-ratio*signal[i];break;
case 1:y=y0-ratio*signal_out[i];break;
}
if(i==0) moveto(x0,y0);
else lineto(x,y);
}
}
void xxcov(unsigned int Num)
{
int k,n;
for (k=1;k<=Num ;k++)
{for(n=k;n<=N-k;n++)
signal_out[k]+=signal[n+k]*signal[n];
signal_out[k]=signal_out[k]/(n-k)/20;
}
}
void zuobiao(int Ax0,int Ay0,int Ax,int Lx0,int Ly0,int Ly,int xi,int yj)
{ int i,j;
line(Ax0,Ay0,Ax,Ay0);
for(i=0;i<32;i++)
{
line(Ax0+xi,Ay0,Ax0+xi,Ay0-5);
xi+=15;
}
line(Ax,Ay0,Ax-10,Ay0-10);
line(Ax,Ay0,Ax-10,Ay0+10);
line(Lx0,Ly0,Lx0,Ly);
for(j=0;j<10;j++)
{
line(Lx0,Ly0+yj+15,Lx0+5,Ly0+yj+15);
yj+=15;
}
line(Lx0,Ly0,Lx0-10,Ly0+10);
line(Lx0,Ly0,Lx0+10,Ly0+10);
setcolor(10);
outtextxy(Lx0+10,Ay0+10,"0");
outtextxy(Ax-10,Ay0+10,"t");
outtextxy(Lx0-30,Ly0+10,"A(w)");
} |