混合中值滤波器 ( Hybrid Median Filter ) C++ 实现

来源:互联网 发布:淘宝客返利源码下载 编辑:程序博客网 时间:2024/04/28 11:23

混合中值滤波器 ( Hybrid Median Filter ) C++ 实现

在中值滤波器和均值滤波器之后, 我们看到是中值滤波器的改版, 这个名字我实在不好把握 Hybrid Median Filter实在不知道翻译成什么比较妥当.只好沿用了混合动力车里面的混合二字, 姑且把这种滤波器命名为混合中值滤波器. 这个滤波器的工作流程较之原先有些繁琐, 来看看这张图

 

 

图截的有些模糊, 但是还是看出了大致的流程, 首先当前像素的上下左右和自身取中值 , 然后左上右上左下右下和自身取中值 , 完了前面的两个值和当前像素值再取一次中值 , 得到的值就是最后的终极像素值了. 可以看到这个流程还是有些复杂的.. 那他的效果如何捏? 我们还是和前几次一样来观察一把:

 

原图                                                                           HMF之后:

 

 

噪声污染:                                                                   HMF之后:

 

 

 

从前面的图片可以看到, 图片从高锐度经由混合中值滤波之后, 锐度下降了. 但是在去噪声的环节上, 这个所谓的混合中值滤波器表现的甚至不如中值滤波来的效果好, 当然因为这里的噪声是随机的, 可能有些因素在其中. 但从原理上分析.这种滤波器确实存在不能过滤掉的可能, 原因在什么地方呢? 且看我们这个大图中的一个小局部:

 

 

把图放大之后看的很清楚了, 在红色的圆圈圈出来的地方, 不出意外的发现了水平连续的3个白色像素. 再联想到我们之前经过HMF之后的效果图就不难得出结论, 就是者连续的3个点造成了最后的这个白色像素. 怎么说呢? 很简单, HMF的第一步过程中, 因为我们选择的点是5各点, 上下左右中, 那么经过计算, 就是白色无疑了, 不管第二步得到什么像素, 在第三步的时候, 2个白色取中值, 肯定得到的白色像素了! 仔细想来确实是这个么道理.  但是median filter的时候因为要整体考虑9个像素的中值, 这里很有可能就不是白色了! 所以这个混合中值滤波器会在保持线条的边缘上有独到之处(因为比较容易保持联系像素的颜色不受伤害), 而消除噪声还是median filter表现更胜一筹.

 

老规矩, 最后再贴一下处理的函数代码:

 

view plaincopy to clipboardprint?

unsigned char median(unsigned char* elements, int width)  

{  

    //   Order elements (only half of them)  

    for (int i = 0; i < (width >> 1) + 1; ++i)  

    {  

        //   Find position of minimum element  

        int min = i;  

        for (int j = i + 1; j < width; ++j)  

            if (elements[j] < elements[min])  

                min = j;  

        //   Put found minimum element in its place  

        unsigned char temp = elements[i];  

        elements[i] = elements[min];  

        elements[min] = temp;  

    }  

    //   Get result - the middle element  

    return elements[width >> 1];  

}  

/** 

** method to remove noise from the corrupted image by hybrid median value 

* @param corrupted input grayscale binary array with corrupted info 

* @param smooth output data for smooth result, the memory need to be allocated outside of the function 

* @param width width of the input grayscale image 

* @param height height of the input grayscale image 

*/ 

void hybridMedianFilter (unsigned char* corrupted, unsigned char* smooth, int width, int height)  

{  

    memcpy ( smooth, corrupted, width*height*sizeof(unsigned char) );  

    for (int j=1;j<height-1;j++)  

    {  

        for (int i=1;i<width-1;i++)  

        {  

            unsigned char window[5];  

            unsigned char results[3];  

            //   Pick up cross-window elements  

            window[0] = corrupted[(j - 1) * width + i];  

            window[1] = corrupted[j * width + i - 1];  

            window[2] = corrupted[j * width + i];  

            window[3] = corrupted[j * width + i + 1];  

            window[4] = corrupted[(j + 1) * width + i];  

            //   Get median  

            results[0] = median(window, 5);  

            //   Pick up x-window elements  

            window[0] = corrupted[(j - 1) * width + i - 1];  

            window[1] = corrupted[(j - 1) * width + i + 1];  

            window[2] = corrupted[j * width + i];  

            window[3] = corrupted[(j + 1) * width + i - 1];  

            window[4] = corrupted[(j + 1) * width + i + 1];  

            //   Get median  

            results[1] = median(window, 5);  

            //   Pick up leading element  

            results[2] = corrupted[j * width + i];  

            //   Get result  

            smooth[j*width+i] = median(results, 3);  

        }  

    }  

} 

因为要取中值, 还附加了一个取中值的函数median:)

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/hhygcy/archive/2009/07/07/4327618.aspx

 

原创粉丝点击