opencv学习笔记(十)-- 图像模糊去噪(中值滤波和双边滤波)

文章目录

  • 中值滤波
    • 中值滤波API
    • 代码实例
  • 双边滤波
    • 双边滤波API
    • 代码实例
  • 使用filter2d()函数对图像进行锐化处理
  • 关于滤波和模糊

之前我们学习了均值滤波和高斯滤波,并且在opencv中进行了应用,接下来还有两种滤波方式,中值滤波和双边滤波

中值滤波

中值滤波是一种统计排序滤波器,将一个区域(例如3×3大小的邻域)中的像素点进行统计排序,找到像素值的中位数来替换邻域中心的像素值。

中值滤波对于椒盐噪声有很好的抑制作用,因为椒盐噪声属于像素值过大或过小,如果使用中值来确定邻域中心像素值,那么就可以很好地过滤掉椒盐噪声。

中值滤波API

medianBlur(Mat src, Mat dst, ksize)
  • src:输入图像,图像为1、3、4通道的图像,当模板尺寸为3或5时,图像深度只能为CV_8U、CV_16U、CV_32F中的一个,如而对于较大孔径尺寸的图片,图像深度只能是CV_8U。
  • dst:输出图像,尺寸和类型与输入图像一致,可以使用Mat::Clone以原图像为模板来初始化输出图像dst.
  • ksize: 滤波模板的尺寸大小,必须是大于1的奇数,如3、5、7……

代码实例

Mat src;
src = imread("A:/opencvproject/001.jpg");
if (!src.data)
{
	cout << "img not ex";
	return -1;
}
char input_win[] = "input_window";

namedWindow(input_win, CV_WINDOW_AUTOSIZE);
imshow(input_win, src);

Mat gaublur;
GaussianBlur(src, gaublur, Size(9, 9), 11, 11);
namedWindow("gblur_win", CV_WINDOW_AUTOSIZE);
imshow("gblur_win", gaublur);

Mat medBlur;
medianBlur(src, medBlur, 9);
namedWindow("medBlur", CV_WINDOW_AUTOSIZE);
imshow("medBlur", medBlur);
waitKey(0);

双边滤波

均值滤波无法克服边缘像素信息丢失的缺陷,高斯滤波虽然克服了该缺陷但是也无法完全避免。
而高斯双边滤波是既考虑了空间位置(空间域核)的不同,也考虑了像素值(值域核)的不同的边缘保留滤波方法,避免了边缘信息的丢失,保留了图像轮廓(可以用于图像美颜)。

双边滤波API

bilateralFilter(Mat src, Mat dst, int d,double sigmaColor, double sigmaSpace,int borderType = BORDER_DEFAULT);
  • src:输入图像,即源图像,需要为8位或者浮点型单通道、三通道的图像。
  • dst,即目标图像,需要和源图片有一样的尺寸和类型,可以使用Mat::Clone以原图像为模板来初始化输出图像dst
  • d:表示在过滤过程中每个像素邻域的直径。如果这个值我们设其为非正数,那么OpenCV会从第五个参数sigmaSpace来计算出它来。
  • sigmaColor:颜色空间滤波器的sigma值。这个参数的值越大,就表明该像素邻域内有更宽广的颜色会被混合到一起,产生较大的半相等颜色区域。(也就是说,在指定半径内,和邻域中心像素值的差值小于这个值的像素点才会被混合计算进来)
  • sigmaSpace:坐标空间中滤波器的sigma值,坐标空间的标注方差。他的数值越大,意味着越远的像素会相互影响,从而使更大的区域足够相似的颜色获取相同的颜色。当d>0,d指定了邻域大小且与sigmaSpace无关。否则,d正比于sigmaSpace
  • borderType:用于推断图像外部像素的某种边界模式。注意它有默认值BORDER_DEFAULT

代码实例

Mat src;
src = imread("A:/opencvproject/001.jpg");
if (!src.data)
{
	cout << "img not ex";
	return -1;
}
char input_win[] = "input_window";

namedWindow(input_win, CV_WINDOW_AUTOSIZE);
imshow(input_win, src);

Mat gaublur;
GaussianBlur(src, gaublur, Size(9, 9), 11, 11);
namedWindow("gblur_win", CV_WINDOW_AUTOSIZE);
imshow("gblur_win", gaublur);

Mat bilateralBlur;
bilateralFilter(src, bilateralBlur, 9, 100, 5);
namedWindow("bilateralBlur", CV_WINDOW_AUTOSIZE);
imshow("bilateralBlur", bilateralBlur);
waitKey(0);

和原图进行对比:
opencv学习笔记(十)-- 图像模糊去噪(中值滤波和双边滤波)_第1张图片

  • 可以看出,相比于原图,图像进行了模糊处理,但是图像的边缘还是十分清晰的。可以与高斯模糊的结果进行对比,对比效果会更加地明显。

和高斯模糊进行对比:
opencv学习笔记(十)-- 图像模糊去噪(中值滤波和双边滤波)_第2张图片

使用filter2d()函数对图像进行锐化处理

锐化时,使用的卷积核为:
opencv学习笔记(十)-- 图像模糊去噪(中值滤波和双边滤波)_第3张图片

Mat resultImg;
Mat kernel = (Mat_<int>(3,3)<< 0,-1, 0, -1. 5, -1, 0, -1, 0);
filter2D(bilateralBlur, resultImg, -1, kernel, Point(-1, -1), 0);//对双边滤波后的图像进行锐化处理可以使图像更加生动
imshow("Final Result", resultImg);
waitKey(0);

关于滤波和模糊

滤波可以分为低通滤波和高通滤波

高斯滤波是用高斯函数作为滤波函数的滤波操作

  • 如果是低通滤波,那么就是模糊
  • 如果是高通滤波,那么就是锐化

图像的噪声一般集中在高频段,所以使用低通滤波可以去除图像的噪声。

同时图像边缘信息也主要集中在其高频部分,所以使用模糊操作会出现图像边缘和图像轮廓模糊的情况。

为了减少这类不利效果的影响,就需要利用图像锐化技术,使图像的边缘变得清晰。

图像锐化处理的目的是为了使图像的边缘、轮廓线以及图像的细节变得清晰。

经过平滑的图像变得模糊的根本原因是因为图像受到了平均或积分运算,因此可以对其进行逆运算(如微分运算)就可以使图像变得清晰。

微分运算是求信号的变化率,由傅立叶变换的微分性质可知,微分运算具有较强高频分量作用。从频率域来考虑,图像模糊的实质是因为其高频分量被衰减,因此可以用高通滤波器来使图像清晰。

但要注意能够进行锐化处理的图像必须有较高的性噪比,否则锐化后图像性噪比反而更低,从而使得噪声增加的比信号还要多,因此一般是先去除或减轻噪声后再进行锐化处理。

总之:图像处理时先对图像进行小型低通滤波处理,比如应用高斯模糊 从而去除噪声,然后再用高通过滤器来检测边缘。

你可能感兴趣的:(opencv,图像处理,C++,opencv)