高斯滤波及其实现

1.滤波算法简介
       图像处理中,常用的滤波算法有均值滤波、中值滤波以及高斯滤波等。均值滤波使用模板内所有像素的平均值代替模板中心像素灰度值,这种方法易收到噪声的干扰,不能完全消除噪声,只能相对减弱噪声;中值滤波计算模板内所有像素中的中值,并用所计算出来的中值体改模板中心像素的灰度值,这种方法对噪声不是那么敏感,能够较好的消除椒盐噪声,但是容易导致图像的不连续性。高斯滤波对图像邻域内像素进行平滑时,邻域内不同位置的像素被赋予不同的权值,对图像进行平滑的同时,同时能够更多的保留图像的总体灰度分布特征。
2.高斯滤波
数值图像处理中,高斯滤波主要可以使用两种方法实现。一种是离散化窗口滑窗卷积,另一种方法是通过傅里叶变化。在这我主要想说说第一种方法的高斯滤波。离散化窗口滑窗卷积的时,主要利用的是高斯核,高斯核一般是一个奇数的大小的高斯模板。常用的高斯模板有如下几种形式:
高斯滤波及其实现
高斯模板中的参数是通过高斯函数计算出来的。计算高斯模板参数时,通过如下公式:
高斯滤波及其实现
x的平方和y的平方分别表示的是邻域内其他像素与邻域内中心像素的距离,Sigmma代表的是标准差。

3.函数说明

InputArray src: 输入图像,可以是Mat类型,图像深度为CV_8U、CV_16U、CV_16S、CV_32F、CV_64F。 
OutputArray dst: 输出图像,与输入图像有相同的类型和尺寸。 
Size ksize: 高斯内核大小,这个尺寸与前面两个滤波kernel尺寸不同,ksize.width和ksize.height可以不相同但是这两个值必须为正奇数,如果这两个值为0,他们的值将由sigma计算。 
double sigmaX: 高斯核函数在X方向上的标准偏差 
double sigmaY: 高斯核函数在Y方向上的标准偏差,如果sigmaY是0,则函数会自动将sigmaY的值设置为与sigmaX相同的值,如果sigmaX和sigmaY都是0,这两个值将由ksize.width和ksize.height计算而来。
int borderType=BORDER_DEFAULT: 推断图像外部像素的某种便捷模式,有默认值BORDER_DEFAULT。

4.代码

#include <iostream>
#include <stdio.h>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>


using namespace std;
using namespace cv;


//定义全局变量
Mat g_srcImage;         //输入图像
Mat g_dstImage;         //输出图像


//定义轨迹条最大值参量
const int g_nKwidthTrackBarMaxValue = 9;
const int g_nKheightTrackBarMaxValue = 9;
const int g_nsigmaXTrackBarMaxValue = 5;
const int g_nsigmaYTrackBarMaxvalue = 5;


//定义每个轨迹条的初始值
int g_nKwidthTrackBarValue = 1;
int g_nKheightTrackBarValue = 1;
int g_nsigmaXTrackBarValue = 1;
int g_nsigmaYTrackBarValue = 1;


int g_kernelWidthValue;
int g_kernelHeightValue;


void on_GaussianBlurTrackbar(int, void*);       //定义回调函数


int main()
{
g_srcImage = imread("text.jpg");


//判断图像是否加载成功
if (!g_srcImage.data)
{
cout << "图像加载失败!" << endl;
return -1;
}
else
cout << "图像加载成功!" << endl << endl;


namedWindow("原图像", WINDOW_NORMAL);         //定义窗口显示属性
imshow("原图像", g_srcImage);


namedWindow("高斯滤波图像", WINDOW_NORMAL);


//定义每个轨迹条名字
char widthTrackBarName[20];
sprintf_s(widthTrackBarName, "核函数width %d", g_nKwidthTrackBarMaxValue);


char heightTrackBarName[20];
sprintf_s(heightTrackBarName, "核函数height %d", g_nKheightTrackBarMaxValue);


char sigmaXTrackBarName[20];
sprintf_s(sigmaXTrackBarName, "核函数sigmaX %d", g_nsigmaXTrackBarMaxValue);


char sigmaYTrackBarName[20];
sprintf_s(sigmaYTrackBarName, "核函数sigmaY %d", g_nsigmaYTrackBarMaxvalue);


//创建轨迹条
createTrackbar(widthTrackBarName, "高斯滤波图像", &g_nKwidthTrackBarValue,
g_nKwidthTrackBarMaxValue, on_GaussianBlurTrackbar);
on_GaussianBlurTrackbar(g_nKwidthTrackBarValue, 0);


createTrackbar(heightTrackBarName, "高斯滤波图像", &g_nKheightTrackBarValue,
g_nKheightTrackBarMaxValue, on_GaussianBlurTrackbar);
on_GaussianBlurTrackbar(g_nKheightTrackBarValue, 0);


createTrackbar(sigmaXTrackBarName, "高斯滤波图像", &g_nsigmaXTrackBarValue,
g_nsigmaXTrackBarMaxValue, on_GaussianBlurTrackbar);
on_GaussianBlurTrackbar(g_nsigmaXTrackBarValue, 0);


createTrackbar(sigmaYTrackBarName, "高斯滤波图像", &g_nsigmaYTrackBarValue,
g_nsigmaYTrackBarMaxvalue, on_GaussianBlurTrackbar);
on_GaussianBlurTrackbar(g_nsigmaYTrackBarValue, 0);


waitKey(0);


return 0;
}


void on_GaussianBlurTrackbar(int, void*)
{
//根据输入的width和height重新计算ksize.width和ksize.height
g_kernelWidthValue = g_nKwidthTrackBarValue * 2 + 1;
g_kernelHeightValue = g_nKheightTrackBarValue * 2 + 1;


//高斯滤波
GaussianBlur(g_srcImage, g_dstImage, Size(g_kernelWidthValue, g_kernelHeightValue),
g_nsigmaXTrackBarValue, g_nsigmaYTrackBarValue);


imshow("高斯滤波图像", g_dstImage);
}

5.运行结果

高斯滤波及其实现