圖像增強-中值濾波


 

中值濾波是一種典型的非線性濾波技術。它在一定條件下可以克服線性濾波器如最小均方濾波,均值濾波等帶來的圖像細節模糊,而且對濾波脈沖干擾及圖像掃描噪聲非常有效。

傳統的中值濾波一般采用含有奇數個點的滑動窗口,用窗口中各點灰度值的中值來替代指定點的灰度值。對於奇數個元素,中值為大小排序后中間的數值;對於偶數個元素,中值為排序后中間兩個元素灰度值的平均值。

中值濾波是一種典型的低通濾波器,主要用來抑制脈沖噪聲,它能徹底濾除尖波干擾噪聲,同時又具有能較好地保護目標圖像邊緣的特點。

標准一維中值濾波器的定義為:

yk = med{ xK-N, xk-N+1, ... ,xk, ... ,xK+N }

式中,med表示取中值操作。中值濾波的濾波方法是對滑動濾波窗口(2N+1)內的像素做大小排序,濾波結果的輸出像素值規定為該序列的中值。

二維中值濾波的窗口形狀和尺寸設計對濾波的效果影響較大,不同的圖像內容和不同的應用要求,往往采用不同的形狀和尺寸。常用的二維中值濾波窗口有線狀,方形,圓形,十字形及圓環形等,窗口尺寸一般選為3。當然也可以采用其他尺寸,主要視具體情況而定。

1.中值的計算關鍵在於對滑動窗口內的像素進行排序,排序算法的選擇是影響中值濾波算法的重要因素。傳統的排序算法是基於冒泡排序法,若窗口中的像素為m,則每個窗口排序需要m(m-2)/2次像素的比較操作,時間復雜度為O(m2)。此外常規的濾波算法每移動一次窗口就要進行一次排序。當一幅圖像的大小為NXN時,則整個計算需要O(m2N2)時間,當窗口較大時,計算量很大,較費時。

2.為了提高中值濾波的實現速度,針對3X3中值濾波,介紹一種快速的並行中值濾波方法。下圖為3X3窗口內像素排列

捕獲

首先對窗口內的每一列分別計算最大值,中值和最小值,這樣就得到了3組數據

最大值組:Max0 = max[P0,P3,P6],Max1 = max[P1,P4,P7],Max2 = max[P2,P5,P8]

中值組: Med0 = med[P0,P3,P6],Med1 = med[P1,P4,P7], Med2 = med[P2,P5,P8]

最小值組:Min0 = Min[P0,P3,P6],Min1 = Min[P1,P4,P7],Min2 = max[P2,P5,P8]

由此可以看到,最大值組中的最大值與最小值組中的最小值一定是9個元素中的最大值和最小值,不可能為中值,剩下7個;中值組中的最大值至少大於5個像素,中值組中的最小值至少小於5個像素,不可能為中值,剩下5個;最大值組中的中值至少大於5個元素,最小值組中的中值至少小於5個元素,不可能為中值,最后剩下3個要比較的元素,即

最大值組中的最小值Maxmin,中值組中的中值Medmed,最小值組中的最大值MinMax;找出這三個值中的中值為9個元素的中值。

算法實現:

View Code
/**********************************************************************
*
* 函數名稱:
* MedFilter(int FilterH, int FilterW, int FilterCX, int FilterCY)
*
* 參數:
* int FilterH     模板的高度        
* int FilterW     模板的寬度
* int FilterCX    模板的中心元素X坐標 ( < FilterW - 1)
* int FilterCY    模板的中心元素Y坐標 ( < FilterH - 1)
*
* 返回值:
* void
*
* 說明:
* 中值濾波的算法
*
**********************************************************************/

void CImgEnhance::MedianFilter(int FilterH, int FilterW, int FilterCX, int FilterCY)
{
    unsigned char*    pSrc;
    unsigned char*    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[FilterH * FilterW];
    for (i = FilterCY; i < m_imgHeight - FilterH ; i++)//+ FilterCY + 1
    {
        for (j = FilterCX; j < m_imgWidth - FilterW ; j++)//+ FilterCX + 1
        {
            
            pDst = m_pImgDataOut + lineByte * (m_imgHeight - 1 - i) + j;
            for (k = 0; k < FilterH; k++)
            {
                for (l = 0; l < FilterW; l++)
                {
                    pSrc = m_pImgData + lineByte * (m_imgHeight - l - i 
                        + FilterCY - k) + j - FilterCX + l;
                    value[k * FilterW + l] = *pSrc;
                }
            }
            *pDst = FindMedianValue(value,FilterW * FilterH);
        }
    }
}

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM