图像模糊 -
-
线性滤波
- 均值滤波
- 高斯滤波
- 中值滤波
2.非线性滤波
- 双边滤波
图像模糊的作用 -
模糊操作时图像处理中最简单和常用的操作之一,该使用的操作之一原因就为了给图像预处理时减低噪声。
模糊操作的基本原理 - (数学的卷积运算)
其中权重核H(K,L)H(K,L)为“滤波系数”上面的式子可以简记为: 通常这些卷积算子计算都是线性操作,所以又叫线性滤波。
均值滤波(归一化滤波)
解释:均值滤波是典型的线性滤波算法,它是指在图像上对目标像素给一个模板,该模板包括了其周围的临近像素(以目标像素为中心的周围8个像素,构成一个滤波模板,即去掉目标像素本身),再用模板中的全体像素的平均值来代替原来像素值。
缺点: 。由于图像边框上的像素无法被模板覆盖,不做所以处理
这当然造成了图像边缘的缺失
OpenCV中提供均值滤波API:
void blur(Mat src,Mat dst, Size(xradius,yradius), Point(-1, -1))
中值滤波(椒盐去燥)
解释:中值,中间值,将数据从小到大排序后的中间值,用3×3大小模板进行中值滤波。对模板中的9个数进行从小到大排序:1,1,1,2 ,2,5,6,6,10。中间值为2所有,中值滤波后(2,2)位置的值变为2.同理对其他像素点。
中值滤波对于椒盐噪声抑制作用较强,但是对于高斯噪声就无能为力了!
OpenCV的提供中值滤波API:
void medianBlur(InputArray src, OutputArray dst, int ksize)
高斯滤波
高斯滤波是一种线性平滑滤波,适用于消除高斯噪声,广泛应用于图像处理的减噪过程。通俗的讲,滤波高斯就是对整幅图像进行加权平均的过程,每一个像素点的值,都由其本身和邻域内的其他像素值经过加权平均后得到。
高斯滤波的具体操作是:用一个模板(或称卷积,掩模)扫描图像中的每一个像素,用模板确定的邻域内像素的加权平均灰度值去替代模板中心像素点的值。
下面我们来看一下高斯函数:
这是一维的
这是二维的
一维函数图
二维函数图
OpenCV中提供API:
void GaussianBlur(InputArray src, OutputArray dst, Size ksize, double sigmaX, double sigmaY=0, int bord
参数解释:
。InputArray src:输入图像,可以是Mat类型,图像深度为CV_8U,CV_16U,CV_16S,CV_32F,CV_64F
。OutputArray dst:输出图像,与输入图像有相同的类型和尺寸
。大小ksize:高斯内核大小,这个尺寸与前面两个滤波内核尺寸不同,ksize.width和ksize.height可以不相同但是这两个值必须为正奇数,如果这两个值为0,他们的值将由西格玛计算。
。double sigmaX:高斯核函数在X方向上的标准偏差(实测影响不大)
。double sigmaY:高斯核函数在Y方向上的标准偏差,如果sigmaY是0,则函数会自动将sigmaY的值设置为与sigmaX相同的值,如果sigmaX和sigmaY都是0,这两个值将由ksize。 width和ksize.height计算而来。具体可以参考getGaussianKernel()函数查看具体细节。建议将size,sigmaX和sigmaY都指定出来
。int borderType = BORDER_DEFAULT:推断图像外部像素的某种便捷模式,有默认值BORDER_DEFAULT,如果没有特殊需要不用更改,具体可以参考borderInterpolate()函数。
双边滤波(非线性滤波)
解释及原理:双边滤波是一种非线性的滤波方法,是结合图像的空间邻近度和像素值相似度的一种折中处理,同时考虑空间与信息和灰度相似性,达到保边去噪的目的,具有简单,非迭代,局部处理的特点之所以能够达到保边去噪的滤波效果是因为滤波器由两个函数构成:一个函数是由几何空间距离决定滤波器系数,另一个是由像素差值决定滤波器系数。
双边滤波器中,输出像素的值依赖于邻域像素的值的加权组合,其公式如下: 权重系数W(I,J,K,L)取决于定义域核 值域状语从句:核 的乘积,也就是
通俗来讲就是双边滤波模板主要有两个模板生成,第一个是高斯模板,第二个是以灰度级的差值作为函数系数生成的模板,然后这两个模板点乘就得到了最终的双边滤波模板,第一个模板是全局模板,所以只需要生成以西,第二个模板需要对每个像素都计算一次。双边滤波器比高斯滤波器多了一个高斯方差Σ-d,它是基于空间分布的高斯滤波函数,所以在边缘附近,离的较远的像素不会太多影响到边缘上的像素,这样就能对边缘附近的像素值予以保存,但是由于保存过多的高频信息,对于彩色图像里的高频噪声,双边滤波器不能够干净的滤掉,只能够对于低频信息进行较好的滤除。
/双边滤波的核函数是空间域核与像素范围域核的综合结果:
//在图像的平坦区域,像素值变化很小,对应的像素范围域权重接近于1,此时空间域权重起主要作用,相当于进行高斯模糊;
//在图像的边缘区域,像素值变化很大,像素范围域权重变大,从而保持了边缘的信息
//
//当远离边界时,即颜色十分相近,颜色权基本一样时,类似于高斯滤波,这样变可平滑处理图像。//
当处在边界时(所谓边界,就是颜色反差极大的地方),边界上的点互相颜色相近,会取极大的权值,
//而边界外的的点,颜色距离很远,权值取的很小(甚重可以忽略不计),这样就保护了边缘
//效率较低,使用比较少
的OpenCV中提供了双边滤波器()函数来实现双边滤波操作,其原型如下:
C++: void bilateralFilter(InputArray src, OutputArray dst, int d, double sigmaColor, double sigmaSpace, int borderType=BORDER_DEFAULT )
参数解释:
。InputArray src:输入图像,可以是Mat类型,图像必须是8位或浮点型单通道,三通道的图像
。OutputArray dst:输出图像,和原图像有相同的尺寸和类型
。int d:表示在过滤过程中每个像素邻域的直径范围。如果这个值是非正数,则函数会从第五个参数sigmaSpace计算该值
。double sigmaColor:颜色空间过滤器的sigma值,这个参数的值月大,表明该像素邻域内有月宽广的颜色会被混合到一起,产生较大的半相等颜***域
。double sigmaSpace:坐标空间中滤波器的sigma值,如果该较大,则意味着颜色相近的较远的像素将相互影响,从而使更大的区域中足够相似的颜色获取相同的颜色。当d > 0时,d指定了邻域大小且与sigmaSpace五官,否则d正比于sigmaSpace。
。int borderType = BORDER_DEFAULT:用于推断图像外部像素的某种边界模式,有默认值BORDER_DEFAULT。
双边滤波器可以很好的保存图像边缘细节而滤除掉低频分量的噪音,但是双边滤波器的效率不是太高,花费的时间相较于其他滤波器而言也比较长。
对于简单的滤波而言,可以将两个西格马值设置成相同的值,如果值<10,则对滤波器影响很小,如果值> 150则会对滤波器产生较大的影响,会使图片看起来像卡通。
代码实现:
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;
int main()//模糊的作用是给 图像预处理时候 减低噪声, 背后的原理是 卷积操作,这些卷积操作都是线性操作,所以叫做线性滤波
{
Mat src1, src2,src3;
src1 = imread("C:\\Users\\马迎伟\\Desktop\\heibao.jpg");
//src2 = imread("C:\\Users\\马迎伟\\Desktop\\a1a.jpg");
if (src1.empty())
{
cout << "could not find src1" << endl;
return -1;
}
imshow("原图",src1);// size 里 是正数 且 为奇数
blur(src1, src2, Size(3, 3), Point(-1, -1));
namedWindow("blur",CV_WINDOW_AUTOSIZE);
imshow("blur",src2);
GaussianBlur(src1, src3, Size(3, 3), 11, 11);
imshow("gaussianblur", src3);
waitKey(0);
return 0;
}
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;
int main()
{
Mat src1, src2, src3,src4;
src1 = imread("C:\\Users\\马迎伟\\Desktop\\douyin.jpg");
//src2 = imread("C:\\Users\\马迎伟\\Desktop\\a1a.jpg");
if (src1.empty())
{
cout << "could not find src1" << endl;
return -1;
}
imshow("原图", src1);
//中值滤波 椒盐去燥
medianBlur(src1,src4,3);
//双边滤波 ,解释在最上边,但是 效率较低
bilateralFilter(src1, src2, 11, 22, 1.5);
imshow("bilateralfilter",src2);
//高斯滤波
GaussianBlur(src1, src3, Size(3, 3), 11, 11);
imshow("gaussianblur", src3);
waitKey(0);
return 0;
}