图像处理算法基础(四)---中值滤波自实现及opencv函数

来源:互联网 发布:淘宝发送宝贝链接 编辑:程序博客网 时间:2024/06/05 19:31

今天用C++实现了中值滤波,opencv中用的cvSmooth,平滑方法选CV_MEDIAN即为中值滤波,下面是自己用代码实现的中值滤波。
先说说原理:中值滤波法是一种非线性平滑技术,它将每一像素点的灰度值设置为该点某邻域窗口内的所有像素点灰度值的中值.
中值滤波是基于排序统计理论的一种能有效抑制噪声的非线性信号处理技术,中值滤波的基本原理是把数字图像或数字序列中一点的值用该点的一个邻域中各点值的中值代替,让周围的像素值接近的真实值,从而消除孤立的噪声点。方法是用某种结构的二维滑动模板,将板内像素按照像素值的大小进行排序,生成单调上升(或下降)的为二维数据序列。二维中值滤波输出为g(x,y)=med{f(x-k,y-l),(k,l∈W)} ,其中,f(x,y),g(x,y)分别为原始图像和处理后图像。W为二维模板,通常为3*3,5*5区域,也可以是不同的的形状,如线状,圆形,十字形,圆环形等。

区域越大滤波效果越好,本人在此选用的是5X5的掩模,代码如下。

inline unsigned char GetMedianValue(int * bArray, int iFilterLen) 

    int i,j; 
    unsigned char tempV; 
     
    // 用冒泡法对数组进行排序 
    for (j = 0; j < iFilterLen - 1; j ++) 
    { 
        for (i = 0; i < iFilterLen - j - 1; i ++) 
        { 
            if (bArray[i] > bArray[i + 1]) 
            { 
                // 互换 
                tempV = bArray[i]; 
                bArray[i] = bArray[i + 1]; 
                bArray[i + 1] = tempV; 
            } 
        } 
    } 
     
    // 计算中值 
    if ((iFilterLen & 1) > 0) 
    { 
        // 数组有奇数个元素,返回中间一个元素 
        tempV = bArray[(iFilterLen + 1) / 2]; 
    } 
    else 
    { 
        // 数组有偶数个元素,返回中间两个元素平均值 
        tempV = (bArray[iFilterLen / 2] + bArray[iFilterLen / 2 + 1]) / 2; 
    } 
 
    return tempV; 
};

int  picProcessBasics::IMGMedianFilter(IplImage* pImg,IplImage* pDestImg,int maskSize)
{
 int FilterW=0;
 int FilterH=0;
 int FilterCenterX=0;
 int FilterCenterY=0;
 int aValue[64]={0};//滤波掩模

 FilterW=maskSize;
 FilterH=maskSize;
 FilterCenterX=maskSize/2;
 FilterCenterY=maskSize/2;
 cvCopy(pImg,pDestImg,0);
 for(int i = FilterCenterY; i < pImg->height-FilterH+FilterCenterY+1; i++){ 
  for(int j = FilterCenterX; j < pImg->width-FilterW+FilterCenterX+1; j++){ 
 
   // 读取滤波器数组 
            for (int k = 0; k < FilterH; k++) 
            { 
                for (int l = 0; l < FilterW; l++) 
                { 
                    // 指向DIB第i - iFilterMY + k行,第j - iFilterMX + l个象素的指针 
                
                    aValue[k * FilterW + l] = pImg->imageData[pImg->widthStep * (i - FilterCenterY + k) + (j - FilterCenterX + l) ]; 
                } 
            } 
   pDestImg->imageData[pDestImg->widthStep * i + j ]= GetMedianValue(aValue, FilterH * FilterW) ;
    
        } 
    }
 return 0;
}
处理前图像:


处理后图像:


0 0
原创粉丝点击