imgproc模块--图像平滑处理

1.目的
本教程教您怎样使用各种线性滤波器对图像进行平滑处理,相关OpenCV函数如下:blur,GaussianBlur,medianBlur,bilateralFilter

2.原理
(1)平滑 也称 模糊, 是一项简单且使用频率很高的图像处理方法。
(2)平滑处理的用途有很多, 但是在本教程中我们仅仅关注它减少噪声的功用 (其他用途在以后的教程中会接触到)。
(3)平滑处理时需要用到一个 滤波器 。 最常用的滤波器是 线性 滤波器,线性滤波处理的输出像素值 (i.e. g(i,j)) 是输入像素值 (i.e. f(i+k,j+l))的加权和:
卷积操作

h(k,l)称为核,它仅仅是一个加权系数。不妨把 滤波器 想象成一个包含加权系数的窗口,当使用这个滤波器平滑处理图像时,就把这个窗口滑过图像。

3.滤波器类型
(1)归一化块滤波器
最简单的滤波器,输出像素是核窗口内像素的均值(所有像素的加权系数相等),核如下:
imgproc模块--图像平滑处理_第1张图片

(2)高斯滤波器
最有用的滤波器(尽管不是最快的),高斯滤波是将输入数组的每一个像素点与 高斯内核 卷积将卷积和当作输出像素值。
[1]一维高斯分布
imgproc模块--图像平滑处理_第2张图片

不难发现中间像素的加权系数是最大的, 周边像素的加权系数随着它们远离中间像素的距离增大而逐渐减小。

[2]二维高斯分布
二维高斯分布
其中u为均值,sigma为方差,x和y相互独立

(3)中值滤波器
中值滤波器将图像的每个像素用临域像素的中值代替,中值滤波器可以有效剔除噪声点。

(4)双边滤波器
目前我们了解的滤波器都是为了 平滑 图像, 问题是有些时候这些滤波器不仅仅削弱了噪声, 连带着把边缘也给磨掉了。 为避免这样的情形 (至少在一定程度上 ), 我们可以使用双边滤波。 类似于高斯滤波器,双边滤波器也给每一个邻域像素分配一个加权系数。 这些加权系数包含两个部分, 第一部分加权方式与高斯滤波一样,第二部分的权重则取决于该邻域像素与当前像素的灰度差值。

4.部分代码解释
(1)归一化滤波

/*
blur参数解释
src:输入图像
dst:输出图像
size:卷积核大小
Point(-1,-1):(-1,-1)代表卷积核中心,也即平滑点,如果取负值则代表取核中心为锚点
*/
blur(src,dst,size(i,i),Point(-1,-1)

(2)高斯滤波

/*
gaussianBlur参数解释
src:输入图像
dst:输出图像
size:卷积核大小
sigma1:x方向的标准差
sigma2:y方向的标准差
*/
gaussianBlur(src, dst, size(i,i), sigma1, sigma2)

(3)中值滤波

/*
medianBlur参数解释
src:输入图像
dst:输出图像
i:卷积核大小,必须是奇数
*/
medianBlur(src, dst, i)

(4)双边滤波

/*
src:输入图像
dst:输出图像
length:像素的临域直径
sigma_color:颜色空间的标准差
sigma_space:坐标空间的标准差(像素单位)
*/
bilateralFilter(src, dst, length, sigma_color, sigma_space)

5.完整代码
(1)CommonInclude.h

#ifndef COMMON_INCLUDE
#define COMMON_INCLUDE
#include
#include
#include
#include
using namespace std;
using namespace cv;
#endif

(2)Filter.cpp

#include "CommonInclude.h"

int main(int argc, char** argv){
    if(argc < 2){
        cout << "more parameters are required!!!" << endl;
        return(-1);
    }
    Mat src = imread(argv[1]);
    Mat dst;
    if(!src.data){
        cout << "error to read image!!!" << endl;
        return(-1);
    }
    //bilateralFilter
    double sigma_color = 0;
    double sigma_sapce = 0;
    //gaussianBlur
    double sigma_x = 0;
    double sigma_y = 0;
    Size kernel = Size(3,3);
    //medianBlur
    int odd = 3;
    //bilateralFilter
    double length = 3;
    imshow("origin", src);
    //归一化滤波
    /*
    blur参数解释
    src:输入图像
    dst:输出图像
    size:卷积核大小
    Point(-1,-1):(-1,-1)代表卷积核中心,也即平滑点,如果取负值则代表取核中心为锚点
    */
    blur(src, dst, kernel, Point(-1,-1));
    imshow("blur", dst);
    //高斯滤波
    /*
    gaussianBlur参数解释
    src:输入图像
    dst:输出图像
    size:卷积核大小
    sigma1:x方向的标准差
    sigma2:y方向的标准差
    */
    GaussianBlur(src, dst, kernel, sigma_x, sigma_y);
    imshow("gaussianBlur", dst);
    //中值滤波
    /*
    src:输入图像
    dst:输出图像
    odd:滤波器大小,必须是奇数
    */
    medianBlur(src, dst, odd);
    imshow("medianBlur", dst);
    //双边滤波
    /*
    src:输入图像
    dst:输出图像
    length:临域像素直径
    sigma_color:颜色空间标准差
    sigma_sapce:坐标空间标准差
    */
    bilateralFilter(src, dst, length, sigma_color, sigma_sapce);
    imshow("bilateralFilter", dst);
    waitKey(0);
    return(0);
}

参考文献
1.http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/imgproc/gausian_median_blur_bilateral_filter/gausian_median_blur_bilateral_filter.html#smoothing

你可能感兴趣的:(opencv学习笔记)