图像处理:平滑滤波
Posted Dillon2015
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了图像处理:平滑滤波相关的知识,希望对你有一定的参考价值。
平滑处理,有时也称模糊处理,是图像处理领域最常用的操作。平滑的目的主要是用来去除噪声。通常平滑操作是通过卷积操作(注:实际上是相关操作,后面的叙述对这两个操作不加区分)完成。下面介绍几种常用的平滑滤波操作。
均值滤波
-
均值滤波是最简单的一种滤波操作,每个被滤波像素通过它邻近像素均值计算得到。
-
均值滤波的kernel如下:
高斯滤波
-
高斯滤波的核是通过高斯函数构建,越靠近中心的像素的值越大,这也反映了图像空域间关系,越邻近的像素相关性越强。
-
二维高斯函数如下:
中值滤波
-
以kernel里像素的中值作为被滤波后像素的值。
-
中值滤波法是一种非线性平滑技术。
-
中值滤波法对消除椒盐噪音非常有效。
双边滤波
-
上面的滤波方法在平滑图像时不仅会平滑噪声,往往还会模糊图像边缘。这是由于它们构造kernel时只用了空间位置信息。
-
双边滤波构造kernel不仅使用空间位置信息,还会使用颜色信息。
在opencv里提供了各种滤波器的调用接口,代码如下:
#include<opencv2/opencv.hpp>
using namespace cv;
using namespace std;
int main()
namedWindow("Smoothing Demo", WINDOW_AUTOSIZE);
Mat src = imread("G:\\\\opencvDemo\\\\lena.jpg");
Mat blurImg;
Mat gaussianImg;
Mat medianImg;
Mat bilteralImg;
Mat boxImg;
Mat filter2DImg;
blur(src, blurImg, Size(5, 5));
boxFilter(src, boxImg, -1, Size(5, 5), Point(-1, -1), true);
GaussianBlur(src, gaussianImg, Size(5, 5),0,0);
medianBlur(src, medianImg, 5);
bilateralFilter(src, bilteralImg, 5, 10, 2.5);
Mat kernal = Mat::ones(Size(5, 5), CV_8UC1);
filter2D(src, filter2DImg, -1, kernal);
//imshow("Smoothing Demo", bilteralImg);
imwrite("blurImg55.jpg", blurImg);
imwrite("boxImg55.jpg", boxImg);
imwrite("gaussianImg55.jpg", gaussianImg);
imwrite("medianImg55.jpg", medianImg);
imwrite("bilteralImg55.jpg", bilteralImg);
imwrite("filter2DImg55.jpg", filter2DImg);
//waitKey(0);
return 0;
实验效果:
原始图像lena.jpg如下:
均值滤波:
滤波函数:blur()
void cv::blur ( InputArray src,
OutputArray dst,
Size ksize,
Point anchor = Point(-1,-1),
int borderType = BORDER_DEFAULT
)
src : 输入图像
dst : 输出图像
ksize : kernel尺寸
anchor: 被滤波像素在kernel中的位置,默认Point(-1,-1)表示在kernel中心
borderType:图像边界填充方式
下图分别是kernel大小为3x3和5x5时的实验效果:
高斯滤波:
滤波函数:GaussianBlur()
void cv::GaussianBlur ( InputArray src,
OutputArray dst,
Size ksize,
double sigmaX,
double sigmaY = 0,
int borderType = BORDER_DEFAULT
)
src : 输入图像
dst : 输出图像
ksize : kernel尺寸
sigmaX: Gaussian kernel在X方向的标准差
sigmaY: Gaussian kernel在Y方向的标准差,如果sigmaY=0则sigmaY会被设为和sigmaX相等。如果sigmaX和sigmaY都为0,则它们会根据ksize.width和ksize.height计算得出。
borderType:图像边界填充方式
下图分别是kernel大小为3x3和5x5时的实验效果:
中值滤波:
滤波函数:medianBlur()
void cv::medianBlur ( InputArray src,
OutputArray dst,
int ksize
)
src : 输入图像
dst : 输出图像
ksize : kernel尺寸
下图分别是kernel大小为3x3和5x5时的实验效果:
双边滤波:
void cv::bilateralFilter ( InputArray src,
OutputArray dst,
int d,
double sigmaColor,
double sigmaSpace,
int borderType = BORDER_DEFAULT
)
src : 输入图像
dst : 输出图像
d : 计算滤波时邻域像素的直径,如果非正数将通过sigmaSpace计算得到。
sigmaColor:颜色空间的影响因子。
sigmaSpace:空域的影响因子。
borderType:图像边界填充方式
下图分别是kernel大小为3x3和5x5时的实验效果:
补充:
下面补充两个滤波函数:
1、boxFilter()
void cv::boxFilter ( InputArray src,
OutputArray dst,
int ddepth,
Size ksize,
Point anchor = Point(-1,-1),
bool normalize = true,
int borderType = BORDER_DEFAULT
)
normalize = true时,计算结果和均值滤波相同
normalize = false时,滤波后像素值为kernel内像素值的和
kernel如下:
下图是normalize = false,ksize为3x3时的结果:
2、filter2D()
void cv::filter2D ( InputArray src,
OutputArray dst,
int ddepth,
InputArray kernel,
Point anchor = Point(-1,-1),
double delta = 0,
int borderType = BORDER_DEFAULT
)
kernel是要使用的滤波核,可以自己根据需求随意构建
下图构建了一个3x3全1的滤波核,可以验证结果与上图相同:
小结
以上便是平滑滤波的基本内容,关键在于滤波核的选择。
欢迎留言交流。
以上是关于图像处理:平滑滤波的主要内容,如果未能解决你的问题,请参考以下文章
OpenCV-Python 图像平滑处理2:blur函数及滤波案例
OpenCV-Python 图像平滑处理2:blur函数及滤波案例