zoukankan      html  css  js  c++  java
  • 图像处理基础(3):均值滤波器及其变种

    均值滤波器可以归为低通滤波器,是一种线性滤波器,其输出为邻域模板内的像素的简单平均值,主要用于图像的模糊和降噪。
    均值滤波器的概念非常的直观,使用滤波器窗口内的像素的平均灰度值代替图像中的像素值,这样的结果就是降低图像中的“尖锐”变化。这就造成,均值滤波器可以降低噪声的同时,也会模糊图像的边缘。均值滤波器的处理结果是过滤掉图像中的“不相关”细节,其中“不相关”细节指的是:与滤波器模板尺寸相比较小的像素区域。

    根据均值计算方法的不同,均值滤波器有以下几种:

    • 算术均值滤波器
    • 几何均值滤波器
    • 谐波均值滤波器
    • 逆谐波均值滤波器

    算术均值滤波器 Arithmetic Mean Filter

    这是最简单的均值滤波器,可以去除均匀噪声和高斯噪声,但会对图像造成一定程度的模糊。
    (S_xy)表示中心点在((x,y))处,大小为(m imes n)的滤波器窗口。算术均值滤波器就是简单的计算窗口区域的像素均值,然后将均值赋值给窗口中心点处的像素:

    [ f(x,y) = frac{1}{mn}sum_{(x,y) in S_{xy}} g(s,t) ]

    其中,(g(s,t))表示原始图像,(f(x,y))表示均值滤波后得到的图像。
    基于上述公式,可以很容易的得到的算术均值滤波器的窗口模板,下面以(3 imes 3)为例

    [ frac{1}{9} left [ egin{array}{c} 1 & 1 & 1 \ 1& 1 & 1 \ 1 & 1 & 1 end{array} ight ] ]

    在OpenCV中,函数blur表示使用该模板的均值滤波器,其声明如下:

    void blur( InputArray src, OutputArray dst,
                            Size ksize, Point anchor = Point(-1,-1),
                            int borderType = BORDER_DEFAULT );
    

    src是输入图像,dst为输出图像;ksize是滤波器模板窗口的大小;后两个参数分别表示,待处理像素在模板窗口的位置,默认值是窗口的中心位置,所以窗口的大小一般为奇数,最后一个参数表示对编解类型的处理,使用默认值即可。其调用示例blur(src,dst,Size(5,5),模板窗口的大小为(5 imes 5)

    盒状滤波器

    当滤波器的模板的所有的系数都相等时称之为盒状滤波器 Box Filter。其使用的模板如下((3 imes 3) 为例):

    [ alpha left [ egin{array}{c} 1 & 1 & 1 \ 1& 1 & 1 \ 1 & 1 & 1 end{array} ight ] ]

    (alpha = 1)时,盒状滤波器可以很方便的计算图像像素邻域的和,对计算图像的各种积分特性例如图像的协方差矩阵,是很有帮助的。OpenCV中的函数boxFilter就是盒状滤波器,其声明如下:

    void boxFilter( InputArray src, OutputArray dst, int ddepth,
                                 Size ksize, Point anchor = Point(-1,-1),
                                 bool normalize = true,
                                 int borderType = BORDER_DEFAULT );
    

    blur的参数比较类似,所不同的ddepth是滤波后图像的深度,-1表示和原图像的深度相同;参数normalize表示是否有归一化的参数,这是因为在boxFilter使用的模板如下:

    [K = alpha left [ egin{array}{c} 1 & 1 & 1 \ 1& 1 & 1 \ 1 & 1 & 1 end{array} ight ] ]

    其中,

    [ alpha = left { egin{array}{cl} frac{1}{width * height} & where normalize = true \ 1& otherwise end{array} ight. ]

    也就是说,当normalize = true时,这也是一个默认值,其就是一个算术均值滤波器;normalize=false,盒状滤波器的作用就是计算模板窗口内的像素的和,然后将值赋给窗口中心位置的像素,主要用来计算邻域像素的和。

    加权的均值滤波器

    不同于上面的所有像素的系数都是相同的,加权的均值滤波器使用的模板系数,会根据像素和窗口中心像素的距离而取不同的系数。赋予中心点最高的权重,然后随着离中心点的距离增加而减小系数,这样做的目的是在平滑图像的同时尽量降低对图像的模糊。最常用的加权模板如下((3 imes 3))为例:

    [frac{1}{16}left [ egin{array}{ccc} 1 & 2 & 1 \ 2 & 4 & 2 \ 1 & 2 & 1 end{array} ight ] ]

    其他的一些非线性均值滤波器

    除了上述算术均值滤波器,根据计算均值方法的不同还有几种均值滤波。

    几何均值滤波器 Geometric Mean Filter其公式如下:

    [ f(x,y) = left[ prod_{(s,t)in S_{xy}g(s,t)} ight]^{frac{1}{mn}} ]

    滤波后图像的像素由模板窗口内像素的乘积的(frac{1}{mn})幂给出。 和算术均值滤波器相比,几何均值滤波器能够更好的取出高斯噪声,并且能够更多的保留图像的边缘信息。但,其对0值是非常敏感的,在滤波器的窗口内只要有一个像素的灰度值为0,就会造成滤波器的输出结果为0。

    谐波均值滤波器 Harmonic Mean Filter 其公式如下:

    [f(x,y) = frac{mn}{sumlimits_{(x,y) in S_{xy}}frac{1}{g(s,t)}} ]

    谐波均值滤波器对盐粒噪声(白噪声)效果较好,不适用于胡椒噪声;比较适合处理高斯噪声。

    逆谐波均值滤波器 Contra-Harmonic Mean Filter其公式如下:

    [f(x,y) = frac{sumlimits_{(x,y) in S_{xy}}g(s,t)^{Q+1}}{sumlimits_{(x,y) in S_{xy}}g(s,t)^{Q}} ]

    其中Q称为滤波器的阶数,该滤波器可以用来消除椒盐噪声。但是需要不同同时处理盐粒噪声和胡椒噪声,当Q为正时,可以消除胡椒噪声;当Q为负时,消除盐粒噪声。当Q=0时,该滤波器退化为算术均值滤波器;Q=-1时,退化为谐波均值滤波器。

    (Y_p)均值滤波器 非线性均值滤波器中的一种,其公式如下:

    [ f(x,y) = left[ sumlimits_{(x,y) in S_{xy}} frac{g(s,t)^P}{N} ight ]^{frac{1}{P}} ]

    P为负数时可以有效的滤去盐粒(白)噪声,正的异常值;P为正时可以过滤胡椒(黑)噪声,负的异常值。

    基于OpenCV的实现

    上述滤波器的实现大同小异,只是计算均值的方法不同。

        Mat tmp;
        copyMakeBorder(m, tmp, ksize / 2, ksize / 2, ksize / 2, ksize / 2, BorderTypes::BORDER_REFLECT); // 扩展边界
        int rows = tmp.rows - ksize / 2;
        int cols = (tmp.cols - ksize / 2) * tmp.channels();
        for (int i = ksize / 2; i < rows - ksize / 2; i++)
        {
            for (int j = ksize / 2; j < cols - ksize / 2; j++)
            {
               // 遍历窗口内的像素,计算均值
            }
        }
        Rect rect(ksize / 2, ksize / 2, m.cols, m.rows);
        m = tmp(rect);
    

    下面就不再贴全的代码,只给出根据不同的公式计算均值的代码。
    几何均值滤波器

    // 取得窗口像素
                double mul = 1;
                for (int a = -ksize / 2; a <= ksize / 2; a++)
                {
                    for (int b = -ksize / 2; b <= ksize / 2; b++)
                    {
                        mul *= tmp.at<uchar>(i + a, j + b);
                    }
                }
                auto pixel = pow(mul, 1.0 / (ksize * ksize));
                if (pixel < 0)
                    pixel = 0;
                else if (pixel >= 255)
                    pixel = 255;
                tmp.at<uchar>(i, j) = static_cast<uchar>(pixel);
    

    基本就是遍历图像的像素,然后在滤波器的窗口内根据均值的计算方式计算均值;几何滤波器,就是将滤波器窗口内的像素乘积,然后去乘积的(frac{1}{ksize *ksize})幂。需要说明的是:几何均值滤波器有个致命的缺陷,那就是当窗口内像素只要有一个值为0,则其计算得到的值就是0,这在去去噪时表现的比较明显,例如:

    由于噪声的污染比较严重,在使用几何均值滤波器去噪时,会得到一块黑色区域(灰度值为0)。

    加权的均值滤波器

                // 取得窗口像素
                int sum = 0;
                  int weightSum = 0;
                for (int a = -ksize / 2; a <= ksize / 2; a++)
                {
                    for (int b = -ksize / 2; b <= ksize / 2; b++)
                    {
                        auto weight = pow(2, ksize - abs(a) - abs(b) - 1);
                        weightSum += weight;
                        sum += weight * tmp.at<uchar>(i + a, j + b);
                    }
                }
                auto pixel = static_cast<int>(sum / weightSum);
                if (pixel < 0)
                    pixel = 0;
                else if (pixel > 255)
                    pixel = 255;
                tmp.at<uchar>(i,j) = pixel;
    

    主要是权值系数的计算,可以发现一定的关系,和中心越近的其权值越高,具体公式:(2^{ksize - a - b - 1},其中a,b为和中心在x,y方向的距离)

    加权的均值滤波器去噪效果和均值滤波器相当,但是在保护图像细节方面比均值滤波器效果要好,上图是(3 imes 3)的滤波器,窗口较小,两者的区别不是较大。
    下图是(7 imes 7)的滤波器,对比就比较明显了。

    至于,其他的几种:谐波滤波器、逆谐波滤波器和(Y_p)均值滤波器,实现都差不多,代码就不再贴出了。

    总结

    均值滤波器能够去除均匀分布和高斯分布的噪声,但是在过滤掉噪声的同时,会对图像造成一定的模糊,使用的窗口越大,造成的模糊也就越明显。
    根据计算均值方法的不同,有多种均值滤波,经常使用的是算术均值滤波器,计算简单,但是对图像造成的模糊交明显;另外,有加权的均值滤波器,给窗口内的像素不同的系数,距离中心越近则系数越大。
    使用加权的均值滤波器,去除噪声的能力和算术均值滤波器相当,但是对图像造成的模糊较轻,能够更好的保护图像的细节。(上面已有对比)

    几何均值滤波器,在过滤噪声的同时也能更好的保护图像的细节,但是有个缺陷:在滤波的过程中,窗口内的像素只要有一个为0,则其得出的值就是0.

    至于余下的几种,在能够去除高斯噪声,并且对椒盐噪声也有一定的作用,具体如下:

    • 谐波均值滤波器 能过滤盐粒噪声,对胡椒噪声无效
    • 逆谐波均值滤波器,当阶数Q为正时,可以过滤胡椒噪声;Q为负时可以过滤盐粒噪声。不能同时对椒盐噪声起作用。
    • (Y_p)均值滤波器, 和逆谐波均值滤波器类似。当P为正时,能够过滤椒盐噪声;P为负时,能够过滤盐粒噪声。
  • 相关阅读:
    About Inside the Azure Storage Outage of November 18th
    Microsoft Azure 的一些限制 Global
    js递归遍历树形json数据,根据关键字查找节点
    如何修改 WordPress 的默认 Gravatar 头像
    flatpickr功能强大的日期时间选择器插件
    express框架,使用 static 访问 public 内静态文件
    nodejs实时的检测系统文件的变化(无需重启服务)
    redis的常用命令
    NPM install -save 和 -save-dev 傻傻分不清
    Git的使用--如何将本地项目上传到Github
  • 原文地址:https://www.cnblogs.com/wangguchangqing/p/6399293.html
Copyright © 2011-2022 走看看