1 中值滤波概述
中值滤波是基于排序统计理论的一种能有效抑制噪声的非线性信号平滑处理技术,它将每一像素点的灰度值设置为该点某邻域窗口内的所有像素点灰度值的中值。
中值滤波的基本原理是把数字图像或数字序列中一点的值用该点的一个邻域中各点值的中值代替,让周围的像素值接近的真实值,从而消除孤立的噪声点。方法是用某种结构的二维滑动模板,将板内像素按照像素值的大小进行排序,生成单调上升(或下降)的为二维数据序列。二维中值滤波输出为g(x,y)=med{f(x-k,y-l),(k,l∈W)} ,其中,f(x,y),g(x,y)分别为原始图像和处理后图像。W为二维模板,通常为3*3,5*5区域,也可以是不同的的形状,如线状,圆形,十字形,圆环形等。
2 中值滤波算法原理
中值滤波数学实现:对一个数字信号序列xj(-∞<j<∞)进行滤波处理时,首先要定义一个长度为奇数的L长窗口,L=2N+1,N为正整数。设在某一个时刻,窗口内的信号样本为x(i-N),…,x(i),…,x(i+N),其中x(i)为位于窗口中心的信号样本值。对这L个信号样本值按从小到大的顺序排列后,其中值,在i处的样值,便定义为中值滤波的输出值。
在实际应用中,随着所选用窗口长度的增加,滤波的计算量将会迅速增加。因此,寻求中值滤波的快速算法,是中值滤波理论的一个重要研究内容。中值滤波的快速算法,一般采用下述三种方式:①直方图数据修正法;②样本值二进制表示逻辑判断法;③数字和模拟的选择网络法。
对中值滤波的理论研究,还集中于统计特性分析和根序列的描述方面。当一个信号序列经一特定窗口长度的中值滤波反复处理后,它会收敛于某一个不再变化的序列,这个序列称为中值滤波的根序列。根序列是描述中值滤波特性的一个重要概念。通过对根序列结构的研究,可以确定原信号序列中,哪些成分可以经中值滤波后保留下来,哪些成分将被抑制。这对确定中值滤波器的窗口长度,提供了重要依据。用VLSI实现的中值滤波器芯片,可供实时处理中应用。
3 中值滤波算法流程
4 中值滤波应用及优势
中值滤波法对消除椒盐噪声非常有效,在光学测量条纹图象的相位分析处理方法中有特殊作用,但在条纹中心分析方法中作用不大.
中值滤波在图像处理中,常用于保护边缘信息,是经典的平滑噪声的方法。
5 中值滤波代码实现
1 // zhongzhilvbo.cpp : 定义控制台应用程序的入口点。 2 // 3 4 #include <stdio.h> 5 #include <math.h> 6 #include <memory.h> 7 #include <conio.h> 8 #include <stdlib.h> 9 #include <windows.h> 10 #include "stdafx.h" 11 //原图象的宽度和高度 12 #define width 352 13 #define higth 288 14 15 int lvbo(unsigned char D[9]) 16 { 17 unsigned int temp; 18 int i,j; 19 20 for(i=0;i<9;i++) 21 { 22 for(j=0;j<9-i;j++) 23 { 24 if(D[i]>D[j+1]) 25 { 26 temp=D[i]; 27 D[i]=D[j+1]; 28 D[j+1]=temp; 29 } 30 } 31 } 32 33 return D[4]; 34 } 35 36 void main() 37 { 38 FILE *fp,*newfp; 39 int i,j; 40 41 if(!(fp=fopen("fmh1.bmp","rb"))) 42 { 43 printf("Open file %s error! ","k.bmp"); 44 return ; 45 } 46 47 if(!(newfp=fopen("fmout.bmp","wb"))) 48 { 49 printf("Open file %s error! ","result.bmp"); 50 return ; 51 } 52 53 unsigned char buffer[54+1024];//定义原图像头缓冲区 54 fread(buffer,1,54+1024,fp);//读取文件头54个字节 55 56 unsigned long length=width*higth;//图像的总象素个数 57 unsigned char readData[higth][width]; //用于存储原图数据的数组 58 unsigned char writeData[higth][width]; //用于存储原图数据的数组 59 60 fread(&readData[0][0], sizeof(unsigned char),length, fp);//从原图读入数据 61 62 for(i=0;i<higth;i++) 63 { 64 for(j=0;j<width;j++) 65 { 66 writeData[i][j]=readData[i][j]; 67 } 68 } 69 70 unsigned char D[9]; //定义选取框 71 for(i=1;i<higth-1;i++) 72 { 73 for(j=1;j<width-1;j++) 74 { 75 D[0]=readData[i-1][j+1]; 76 D[1]=readData[i][j+1]; 77 D[2]=readData[i+1][j+1]; 78 D[3]=readData[i-1][j]; 79 D[4]=readData[i][j]; 80 D[5]=readData[i+1][j]; 81 D[6]=readData[i-1][j-1]; 82 D[7]=readData[i][j-1]; 83 D[8]=readData[i+1][j-1]; 84 writeData[i][j]=lvbo(D); 85 } 86 } 87 88 fwrite(buffer,sizeof(unsigned char),54+1024,newfp); 89 fwrite(writeData,sizeof(unsigned char),length,newfp); 90 fclose(newfp); 91 fclose(fp); 92 93 return ; 94 }
经过中值滤波处理后的对比图片: