1、什么是中值滤波器?
中值滤波器是对滑动窗口内的各像素的灰度值进行排序,将窗口的中心像素的原始灰度值置换为中央值的非线性图像平滑方法,脉冲干扰水平的椒盐噪声的抑制效果好,在抑制随机噪声的同时使边缘模糊
中值滤波器对尖峰脉冲进行滤波。 目的是对过滤后的数据更感兴趣。 滤波数据保持的原图像的变化趋势,同时消除了尖峰脉冲对分析的影响。
以一维信号中值滤波器为例。 对于灰度序列80、120、90、200、100、110、70,如果按大小顺序排列,则其结果为70、80、90、10O、110、120、200,如果其中间位置灰度值为100,则为其中间位置一维中值滤波器实际上以中值替换预定位置(一般为原始信号序列的中心位置)的信号值。 在上述序列的情况下,中值滤波器的结果是序列80、120、90、200、100、110、70中信号序列中心位置的值200被中值100替换的滤波器序列,并且值80、120、 如果该序列中200是噪声信号,那么该方法可以去除噪声点。
二维中值滤波算法对一张图像的像素矩阵取以对象像素为中心的子矩阵窗口,根据需要选择该窗口3 * 3、5 * 5等,对窗口内的像素的灰度进行排序,将中间值作为对应窗口的例子,例如以ooooxoooo上的x为对象像素,与周围的o构成3*3矩阵的排列Array,对这9个要素的灰度进行重新排列,将重新排列后的中间要素Array[4]作为x的新灰度值,由此对象像素x的介质
图像处理中值滤波的实现方法
1 )从图像中的一个采样窗口取出奇数个数据进行排序2 )只需用排序后的中值替换要处理的数据即可进行中值滤波的算法实现过程。 重点是排序,根据最常用的鼓泡进行排序(~过滤区间的数据从小到大进行排序,取中位数。 )如果是奇数个数据,则中央值只有1个,但是如果是偶数个数据,则中央值有2个,所以可以将2个数据平均
以下是用c语言实现中值过滤器的函数。
unsignedchargetmediannum ((int * barray,int iFilterLen ) ) ) ) ) ) ) )。
{
int i,j; //循环变量
无符号char Bt EMP;
//用鼓泡法对数组进行排序
for(j=0; j iFilterLen - 1; j )
{
for(I=0; i iFilterLen - j - 1; I )
{
if(Barray[I]Barray[I1] ) ) )。
{
//调换
bTemp=bArray[i];
bArray[i]=bArray[i 1];
bArray[i 1]=bTemp;
}
}
}
//计算中位数
if((ifilterlen1)0) ) ) ) ) ) )。
{
//数组中有奇数个元素,返回中间的元素
BtEMP=Barray[(ifilterlen1)/2];
}
else
{
//数组中有偶数个元素,返回中间两个元素的平均值
Bt EMP=(barray [ ifilter len/2 ] barray [ ifilter len/21 ] )/2;
}
返回Bt EMP;
}
注: bArray是一个格式指针,通常是一个数组,用于存储要排序的数据
iFilterLen是过滤器的长度
用于图像处理时,像素的可能值范围为0到255,正好在无符号字符范围内,所以函数的返回值为无符号字符范围,如果我们处理的数量是浮点型或其他类型,也可以更改返回值~~返回值是bTemp,也就是我们想得到的中位数
以下是完整的c语言程序,用于图像处理
/* * * * * * * * * * * * * * * * * *
*函数名称:
*媒体过滤器() )
*参数:
* int iFilterH -过滤器高度
* int iFilterW -过滤器宽度
* int iFilterMX -过滤器的中心元素x坐标
* int iFilterMY -过滤器中心元素的y坐标
说明:
*此函数对DIB图像进行中值滤波。
* * * * * * * * * * * * * * * * *
#缉毒组
ine iFilterW 1#define iFilterH 1
#define iFilterMX 1
#define iFilterMY 1
#define WIDTHBYTES(bits) (((bits) + 31) / 32 * 4)
unsigned char GetMedianNum(int * bArray, int iFilterLen);
void MedianFilter(unsigned char *pImg1,unsigned char *pImg,int nWidth,int nHeight)
{
unsigned char *lpSrc; // 指向源图像的指针
unsigned char *lpDst; // 指向要复制区域的指针
int aValue[iFilterH*iFilterW]; // 指向滤波器数组的指针
int i,j,k,l; // 循环变量
int lLineBytes; // 图像每行的字节数
lLineBytes = WIDTHBYTES(nWidth * 8);
for ( i=0;i
(*pImg)=0;
// 开始中值滤波
// 行(除去边缘几行)
for(i = iFilterMY; i < nHeight - iFilterH + iFilterMY + 1; i++)
{
// 列(除去边缘几列)
for(j = iFilterMX; j < nWidth - iFilterW + iFilterMX + 1; j++)
{
// 指向新DIB第i行,第j个象素的指针
lpDst = pImg + lLineBytes * (nHeight - 1 - i) + j;
// 读取滤波器数组
for (k = 0; k < iFilterH; k++)
{
for (l = 0; l < iFilterW; l++)
{
// 指向DIB第i - iFilterMY + k行,第j - iFilterMX + l个象素的指针
lpSrc = pImg1 + lLineBytes * (nHeight - 1 - i + iFilterMY - k) + j - iFilterMX + l;
// 保存象素值
aValue[k * iFilterW + l] = *lpSrc;
}
}
// 获取中值
* lpDst = GetMedianNum(aValue, iFilterH * iFilterW);
}
}
}
unsigned char GetMedianNum(int * bArray, int iFilterLen)
{
int i,j; // 循环变量
unsigned char bTemp;
// 用冒泡法对数组进行排序
for (j = 0; j < iFilterLen - 1; j ++)
{
for (i = 0; i < iFilterLen - j - 1; i ++)
{
if (bArray[i] > bArray[i + 1])
{
// 互换
bTemp = bArray[i];
bArray[i] = bArray[i + 1];
bArray[i + 1] = bTemp;
}
}
}
// 计算中值
if ((iFilterLen & 1) > 0)
{
// 数组有奇数个元素,返回中间一个元素
bTemp = bArray[(iFilterLen + 1) / 2];
}
else
{
// 数组有偶数个元素,返回中间两个元素平均值
bTemp = (bArray[iFilterLen / 2] + bArray[iFilterLen / 2 + 1]) / 2;
}
return bTemp;
}