5.4.4 中值滤波(1)
1.中值滤波的基础理论
中值滤波是由Tukey首先提出的一种典型的非线性滤波技术。它在一定的条件下可以克服线性滤波器如最小均方滤波、均值滤波等带来的图像细节模糊,而且对滤除脉冲干扰及图像扫描噪声非常有效。由于在实际运算过程中不需要图像的统计特征,因此使用方便。
传统的中值滤波一般采用含有奇数个点的滑动窗口,用窗口中各点灰度值的中值来代替指定点的灰度值。对于奇数个元素,中值是指按大小排序后中间的数值;对于偶数个元素,中值是指排序后中间两个元素灰度值的平均值。中值滤波也是一种典型的低通滤波器,主要用来抑制脉冲噪声,它能够彻底滤除尖波干扰噪声,同时又具有能较好地保护目标图像边缘的特点。
标准一维中值滤波器的定义为:
|
| (5-4) |
式中,
表示取中值操作。中值滤波的滤波方法是对滑动滤波窗口
内的像素做大小排序,滤波结果的输出像素值规定为该序列的中值。例如取3×3滑动窗口,中值为窗口内第5个最大的像素值。二维中值滤波的窗口形状和尺寸设计对滤波的效果影响较大,不同的图像内容和不同的应用要求,往往采用不同的形状和尺寸。常用的二维中值滤波窗口有线状、方形、圆形、十字形及圆环形等,窗口尺寸一般选为3,也可以根据滤波效果逐渐增大尺寸,直到获得满意的滤波效果。常用的滤波器为N×N中值滤波器、十字形中值滤波器和N×N最大值滤波器,其他类型的滤波器也可以根据此方法来类推。
中值的计算在于对滑动窗口内像素的排序操作。要进行排序,就必须对序列中的数据像素做比较和交换,数据元素之间的比较次数是影响排序速度的一个重要因素。传统的排序串行算法是基于冒泡排序法,若窗口内像素为m个,则每个窗口排序需要做m(m-2)/2次像素的比较操作,时间复杂度为
。此外,常规的滤波算法使窗口每移动一次,就要进行一次排序,这种做法实际上包含了大量重复比较的过程。若一幅图像的大小为
,则整个计算需要
时间,当窗口较大时计算量很大,较费时。
2.快速并行中值滤波方法的基本理论
为进一步改进中值滤波方法的实现速度,针对3×3中值滤波,介绍一种快速的并行中值滤波方法,通过巧妙设计,避免了大量的重复比较操作,每一窗口排序需要
时间,整个计算需要
时间,易于在硬件处理器上实现并行处理。
快速算法及其实现:为便于说明,将3×3窗口内的各像素分别定义为 ,像素排列如表5-2所示。
表5-2 3×3窗口内像素排列
首先对窗口内的每一列分别计算最大值、中值和最小值,这样就得到3组数据,分别为最大值组、中值组和最小值组。计算过程表示如下:
公式中max表示取最大值操作,med表示取中值操作,min表示取最小值操作。
由此可以看到,最大值组中的最大值与最小值组中的最小值一定是9个像素中的最大值和最小值。除此,中值组中的最大值至少大于5个像素:本列中的最小值和其他两列中的中值和最小值;中值组中的最小值至少小于5个像素:本列中的最大值和其他两列中的最大值和中值。同样,最大值组中的中值至少大于5个像素,最小值组中的中值至少小于5个像素。即最大值组中的最小值为maxmin,中值组中的中值为medmed,最小值组中的最大值为minmax,则滤波结果的输出像素值winmed应该为maxmin、medmed、minmax中的中值。这一计算过程表示如下:
采用该方法,中值的计算仅需做17次比较,与传统算法相比,比较次数减少了近2倍,且该算法十分适用于在实时处理器上做并行处理。
3.算法实现
本算法程序是根据传统的3×3中值滤波方法编写的,采用冒泡排序法查找模板中像素的中值。改进的并行中值滤波方法原理上与传统方法类似,有兴趣的读者可以根据此程序自行编写。CImgEnhance类中的成员函数FindMedianValue()实现计算中值操作,函数MedianFilter()实现中值滤波操作。在对灰度图像进行邻域平均时直接调用MedianFilter()函数即可。以下是FindMedianValue()和MedianFilter()函数的代码实现。
/**************************************** ****************************** * * 函数名称: * FindMedianValue(unsigned char* pTemplate,int templLen) * * 参数: * unsigned char* pTemplate-指向模板数组指针 * int templLen-模板数组的长度 * * 返回值: * unsigned char,中位值 * * 说明:中值滤波中查找模板中像素中值的算法,利用冒泡排序 * * **************************************** ******************************/ unsigned char CImgEnhance::FindMedianValue (unsigned char* pTemplate,int templLen) { int i,j; unsigned char MedianValue;
for(j =0; j<templLen; j++) { for(i =0; i <templLen-j-1; i++) { if(pTemplate[i]>pTemplate[i+1]) { MedianValue=pTemplate[i]; pTemplate[i]=pTemplate[i+1]; pTemplate[i+1]=MedianValue; }
} } if ((templLen&1)>0) { MedianValue=pTemplate[(templLen+1)/2]; } else { MedianValue=(pTemplate[templLen/2]+ pTemplate[templLen/2+1])/2; }
return MedianValue; } /************************************** ******************************** * * 函数名称: * MedianFilter(int windowH, int windowW, int wX0, int wY0) * * 参数: * int windowH-模板窗口的高度 * int windowW-模板窗口的宽度 * int wX0-模板中心元素的X坐标 * int wY0-模板中心元素的Y坐标 * * 返回值: * void * * 说明:中值滤波算法 * * ************************************ **********************************/ void CImgEnhance::MedianFilter(int windowH, int windowW, int wX0, int wY0) { unsigned char *pSrc, *pDst; int i,j,k,l; unsigned char* value; //指向滤波器数组的指针
if(m_pImgDataOut != NULL) { delete []m_pImgDataOut; m_pImgDataOut = NULL; } //计算图像每行的字节数 int lineByte = (m_imgWidth * m_nBitCount / 8 + 3) / 4 * 4;
if(m_nBitCount != 8) { AfxMessageBox("只能处理8位灰度图像!"); return ; } //分配内存,以保存新图像 m_nBitCountOut = m_nBitCount; int lineByteOut = (m_imgWidth * m_nBitCountOut / 8 + 3) / 4 * 4; if (!m_pImgDataOut) { //为处理后的图像分配内存空间 m_pImgDataOut = new unsigned char [lineByteOut * m_imgHeight]; } int pixelByte = m_nBitCountOut / 8; for(i = 0; i < m_imgHeight; i++){ for(j = 0; j < m_imgWidth * pixelByte; j++) *(m_pImgDataOut + i * lineByteOut +j) = * (m_pImgData + i * lineByteOut + j); } //暂时分配内存,以保存滤波器数组 value = new unsigned char[windowH * windowW]; for (i = wY0; i < m_imgHeight - windowH + wY0 + 1; i++) { for (j = wX0; j < m_imgWidth - windowW + wX0 + 1; j++) {
pDst = m_pImgDataOut + lineByte * (m_imgHeight - 1 - i) + j; for (k = 0; k < windowH; k++) { for (l = 0; l < windowW; l++) { pSrc = m_pImgData + lineByte * (m_imgHeight - l - i + wY0 - k) + j - wX0 + l; value[k * windowW + l] = *pSrc; } } *pDst = FindMedianValue(value,windowW * windowH); } } } |
【责任编辑:
夏书 TEL:(010)68476606】