注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

阿弥陀佛

街树飘影未见尘 潭月潜水了无声 般若观照心空静...

 
 
 

日志

 
 
关于我

一直从事气象预报、服务建模实践应用。 注重气象物理场、实况场、地理信息、本体知识库、分布式气象内容管理系统建立。 对Barnes客观分析, 小波,计算神经网络、信任传播、贝叶斯推理、专家系统、网络本体语言有一定体会。 一直使用Java、Delphi、Prolog、SQL编程。

网易考拉推荐

图像增强-中值滤波  

2015-10-29 11:10:56|  分类: 小波 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
图像增强-中值滤波

中值滤波是一种典型的非线性滤波技术。它在一定条件下可以克服线性滤波器如最小均方滤波,均值滤波等带来的图像细节模糊,而且对滤波脉冲干扰及图像扫描噪声非常有效。

传统的中值滤波一般采用含有奇数个点的滑动窗口,用窗口中各点灰度值的中值来替代指定点的灰度值。对于奇数个元素,中值为大小排序后中间的数值;对于偶数个元素,中值为排序后中间两个元素灰度值的平均值。

中值滤波是一种典型的低通滤波器,主要用来抑制脉冲噪声,它能彻底滤除尖波干扰噪声,同时又具有能较好地保护目标图像边缘的特点。

标准一维中值滤波器的定义为:

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个元素的中值。

算法实现:

复制代码
/**********************************************************************
*
* 函数名称:
* 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);
        }
    }
}
复制代码
  评论这张
 
阅读(208)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017