形态学滤波算法

由于系统需要对数据进行实时滤波,所以研究了一下fir,iir和形态学滤波,发现形态学滤波是个相当不错的东东,对滤除尖峰“毛刺”干扰有特别明显的作用。

数学形态学的方法可以理解为一个具有一定直径的小球滚过一段特定的路径,各种信号可以看作是路径上的小坑。由于所有的噪声都有个共同特征一一高频低峰(它们构成非常复杂,由各种混合在眼电信号中的其他成份或眼球快速、微小、空间大小不超过1“的运动导致),这些小坑的径长明显小于小球直径,因此小球球心的滚动轨迹不会受噪声的干扰一一小球球心滚动轨迹即可以看成数学形态学处理后的信号。本系统中用到的数学形态学算子包括腐蚀运算、膨胀运算、开操作、闭操作。

腐蚀的最简单的应用是从图中消除不相关的细节,而膨胀的最简单的应用是将裂缝桥接起来。开运算是先腐蚀再膨胀,开运算一般断开狭窄的间断和消除细的突出物,而闭操作通常消弥狭窄的间断和长细的鸿沟,消除小的孔洞,并填充轮廓线中的断裂。开运算与闭运算的结合使用能使作用对象的轮廓变得光滑。

算法源代码如下:

#include 
#include 
//#include 
//#include 
#include 
#define N 5  //结构元素。大小设置根据滤除波形一个周期中点个数来定。例如:采样率250,滤除50hz,
                                                                 //因为50hz一个周期中有5个点,所以N设为5。          


float x[3*N+2]={0.0};

void openoperate(float input[],float dilation[]) //开运算:先腐蚀再膨胀
{
	int i,k,t;
	float tmp;
	t=2*N+3;
	float erosion[2*N+3];
	for(k=0;kinput[i])
				tmp=input[i];
		}
		erosion[k]=tmp;
	}
	t=t-3;
	for(k=0;kdilation[k])
			tmp=dilation[k];
	}
	return tmp;
}

int main()
{
	clock_t start,end;
	double duration;
	FILE *fd,*m_fd;
	float buffer;
	float filter_data;
	float openresult[2*N-1];

	m_fd=fopen("D:/data.txt","r+");
	if(m_fd==NULL){
		perror("open error!");
		return -1;
	}

	fd=fopen("D:/data1.txt","w+");	
	if(fd==NULL){
		perror("open error!");
		return -1;
	}
	start=clock();
	while(fscanf(m_fd,"%f",&buffer)!=EOF){
		  x[3*N+1]=buffer;

		  openoperate(x,openresult);
	      filter_data=closeoperate(openresult);
		  fprintf(fd,"%f ",filter_data);

		  for(int y=0;y<3*N+1;y++)
			   x[y]=x[y+1];
	}
	end=clock();
	duration=(double)(end-start)/CLOCKS_PER_SEC;
	printf("%f seconds\n",duration);
	fclose(fd);
	fclose(m_fd);
	return 0;
}


图一,对有干扰原始眼电数据进行形态学滤波处理,其中结构元素17个,窗宽5.有图可以看到,形态学对于尖峰的滤波效果特别明显。


图二,将形态学滤波算法加入Qt中,对眼电进行实时滤波处理,效果如图:




你可能感兴趣的:(Qt,滤波算法,形态学)