混合中值滤波器 ( 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