OpenCV图像处理篇之图像平滑

图像平滑与图像模糊是同一概念,主要用于图像的去噪。平滑要使用滤波器,为不改变图像的相位信息,一般使用线性滤波器,其统一形式如下:

其中h称为滤波器的核函数,说白了就是权值。不同的核函数代表不同的滤波器,有不同的用途。

在图像处理中,常见的滤波器包括:

1.归一化滤波器(Homogeneous blur)

也是均值滤波器,用输出像素点核窗口内的像素均值代替输出点像素值。


2.高斯滤波器(Guassian blur)

是实际中最常用的滤波器,高斯滤波是将输入数组的每一个像素点与 高斯内核 卷积将卷积和当作输出像素值。高斯核相当于对输出像素的邻域赋予不同的权值,输出像素点所在位置的权值最大(对应高斯函数的均值位置)。二维高斯函数为,

1.中值滤波器(median blur)

中值滤波将图像的每个像素用邻域(以当前像素为中心的正方形区域)像素的中值代替。对椒盐噪声最有效的滤波器,去除跳变点非常有效。


2.双边滤波器(Bilatrial blur)

为避免滤波器平滑图像去噪的同时使边缘也模糊,这种情况下使用双边滤波器。关于双边滤波器的解释参见


下面的程序将先给标准Lena图像添加椒盐噪声,分别使用4种不同的滤波器进行平滑操作,请注意观察不同滤波器对椒盐噪声的去噪效果!

程序分析及结果
/*
 * FileName : image_smoothing.cpp
 * Author  : xiahouzuoxin @163.com
 * Version  : v1.0
 * Date    : Wed 17 Sep 2014 08:30:25 PM CST
 * Brief    :
 *
 * Copyright (C) MICL,USTB
 */
#include "cv.h"
#include "imgproc/imgproc.hpp"
#include "highgui/highgui.hpp"

using namespace std;
using namespace cv;

const int MAX_KERNEL_LENGTH = 10;

const char *wn_name = "Smoothing";

static void salt(Mat &I, int n);
static void disp_caption(const char *wn_name, Mat src, const char *caption);
static void disp_image(const char *wn_name, Mat I);

/*
 * @brief 
 * @inputs 
 * @outputs
 * @retval 
 */
int main(int argc, char *argv[])
{
    if (argc<2) {
        cout<<"Usage: ./image_smoothing [file name]"<<endl;
        return -1;
    }

Mat I = imread(argv[1], CV_LOAD_IMAGE_GRAYSCALE);
    salt(I, 6000);
    imshow(wn_name, I);
    waitKey(0);

Mat dst;  // Result

/* Homogeneous blur */
    disp_caption(wn_name, I, "Homogeneous blur");
    for (int i=1; i<MAX_KERNEL_LENGTH; i+=2) {
        blur(I, dst, Size(i, i), Point(-1,-1));
        disp_image(wn_name, dst);
    }

/* Guassian blur */
    disp_caption(wn_name, I, "Gaussian blur");
    for (int i=1; i<MAX_KERNEL_LENGTH; i+=2) {
        GaussianBlur(I, dst, Size(i, i), 0, 0);
        disp_image(wn_name, dst);
    }

/* Median blur */
    disp_caption(wn_name, I, "Median blur");
    for (int i=1; i<MAX_KERNEL_LENGTH; i+=2) {
        medianBlur(I, dst, i);
        disp_image(wn_name, dst);
    }

/* Bilatrial blur */
    disp_caption(wn_name, I, "Bilatrial blur");
    for (int i=1; i<MAX_KERNEL_LENGTH; i+=2) {
        bilateralFilter(I, dst, i, i*2, i/2);
        disp_image(wn_name, dst);
    }
    waitKey(0);

return 0;
}


/*
 * @brief  显示提示文字(滤波方法)
 * @inputs 
 * @outputs
 * @retval 
 */
static void disp_caption(const char *wn_name, Mat src, const char *caption)
{
    Mat dst = Mat::zeros(src.size(), src.type());

putText(dst, caption, Point(src.cols/4, src.rows/2), CV_FONT_HERSHEY_COMPLEX, 1, Scalar(255,255,255));

imshow(wn_name, dst);
    waitKey(0);
}

/*
 * @brief  显示图像
 * @inputs 
 * @outputs
 * @retval 
 */
static void disp_image(const char *wn_name, Mat I)
{
    imshow(wn_name, I);
    waitKey(1000);
}


/*
 * @brief  添加椒盐噪声
 * @inputs 
 * @outputs
 * @retval 
 */
static void salt(Mat &I, int n=3000)
{
    for (int k=0; k<n; k++) {
        int i = rand() % I.cols;
        int j = rand() % I.rows;

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/d1d37e7694842526c080d0247f2026a1.html