滑动窗⼝滤波c语⾔,关于中值滤波算法以及C语⾔实现
1、什么是中值滤波?
中值滤波是对⼀个滑动窗⼝内的诸像素灰度值排序,⽤其中值代替窗⼝中⼼象素的原来灰度值,它是⼀种⾮线性的图像平滑法,它对脉冲⼲扰级椒盐噪声的抑制效果好,在抑制随机噪声的同时能有效保护边缘少受模糊。
中值滤波可以过滤尖峰脉冲。⽬的在于我们对于滤波后的数据更感兴趣。滤波后的数据保留的原图像的变化趋势,同时去除了尖峰脉冲对分析造成的影响。
以⼀维信号的中值滤波举例。对灰度序列80、120、90、200、100、110、70,如果按⼤⼩顺序排列,其结果为70、80、90、
10O、110、120、200,其中间位置上的灰度值为10O,则该灰度序列的中值即为100。⼀维信号中值滤波实际上就是⽤中值代替规定位置(⼀般指原始信号序列中⼼位置)的信号值。对前⾯所举的序列⽽⾔,中值滤波的结果是⽤中值100替代序列80、120、90、200、100、110、70中的信号序列中⼼位置值200,得到的滤波序列就是80、120、90、100、100、110、70。如果在此序列中200是⼀个噪声信号,则⽤此⽅法即可去除这个噪声点。
⼆维中值滤波算法是:对于⼀幅图像的象素矩阵,取以⽬标象素为中⼼的⼀个⼦矩阵窗⼝,这个窗⼝可以是3*3 ,5*5 等根据需要选取,对窗⼝内的象素灰度排序,取中间⼀个值作为⽬标象素的新灰度值。窗⼝⽰例如ooooxoooo上⾯x为⽬标象素,和周围o组成3*3矩阵Array,然后对这9个元素的灰度进⾏排序,以排序后的中间元素Array[4]为x的新灰度值,如此就完成对象素x的中值滤波,再迭代对其他需要的象素进⾏滤波即可。
图像处理中,中值滤波的实现⽅法
1:通过从图像中的某个采样窗⼝取出奇数个数据进⾏排序 2:⽤排序后的中值取代要处理的数据即可 中值滤波的算法实现过程,重点是排序,最常⽤的冒泡排序~~ 把滤波区间的数据从⼩到⼤进⾏排序,然后取中值,(如果是奇数个数据,那么中值就只有⼀个了,如果偶数个数据,中值有两个,可以对两个数据再求平均)
下⾯是⼀个C语⾔实现中值滤波的函数:
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;
}
c语言的冒泡排序算法
注:bArray 是⼀个整形指针,我们传⼊的⼀般是⼀个数组,⽤来存储待排序的数据
iFilterLen 是滤波器的长度
⽤在图像处理中时,由于像素的取值范围是0~255,刚好是unsigned char 的范围,所以函数的返回值是unsigned char,如果我们要处理的数是float型,或其他类型,返回值也可以更改~~返回值是bTemp,也即是我们想得到的中值
下⾯是⼀个完整的C语⾔程序,⽤在图像处理中
/*************************************************************************
* 函数名称:
* MedianFilter()
* 参数:
* int iFilterH - 滤波器的⾼度
* int iFilterW - 滤波器的宽度
* int iFilterMX - 滤波器的中⼼元素X坐标
* int iFilterMY - 滤波器的中⼼元素Y坐标
* 说明:
* 该函数对DIB图像进⾏中值滤波。
************************************************************************/
#define 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;
}

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。