[OpenCV] 09-模糊图像

模糊图像

简介:本文主要记录了均值滤波、高斯滤波、中值滤波和双边滤波。

一 模糊原理

  • Smooth/Blur 是图像处理中最简单和常用的操作之一
  • 使用该操作的原因之一就为了给图像预处理时候减低噪声
  • 使用Smooth/Blur操作其背后是数学的卷积计算
  • 通常这些卷积算子计算都是线性操作,所以又叫线性滤波
    [OpenCV] 09-模糊图像_第1张图片
    假设有6x6的图像像素点矩阵。
  • 卷积过程:6x6上面是个3x3的窗口,从左向右,从上向下移动,黄色的每个像素点值之和取平均值赋给中心红色像素作为它卷积处理之后新的像素值。每次移动一个像素格。
    [OpenCV] 09-模糊图像_第2张图片

二 归一化盒子滤波(均值滤波)

[OpenCV] 09-模糊图像_第3张图片
取周围K_width*K_height的像素的平均值代替操作点的像素。

三 高斯滤波

[OpenCV] 09-模糊图像_第4张图片[OpenCV] 09-模糊图像_第5张图片

★高斯滤波与均值滤波的差别在于取均值的过程中,高斯滤波方法中越靠近处理像素点的像素点所占的权重越大,中心的权重最大,其优点在于一定程度上保留了原来图像的特征
★高斯滤波就是对整幅图像进行加权平均的过程,每一个像素点的值,都由其本身和邻域内的其他像素值经过加权平均后得到。

四 中值滤波

  • 统计排序滤波器
  • 中值对椒盐噪声有很好的抑制作用

(因为中值滤波是用领域的中值代替该点的像素值,所有会掩盖掉图片中的极大值值或者极小值,也就去除掉了图片中的椒盐噪点)

同理:存在最小值滤波和最大值滤波
[OpenCV] 09-模糊图像_第6张图片

五 双边滤波

  • 均值模糊无法克服边缘像素信息丢失缺陷。原因是均值滤波是基于平均权重
  • 高斯模糊部分克服了该缺陷,但是无法完全避免,因为没有考虑像素值的不同(例如存在像素值差值过大的点不应考虑进去,否者会掩盖掉该差异特征,即边缘信息丢失了)。
  • 高斯双边模糊 – 是边缘保留的滤波方法,避免了边缘信息丢失,保留了图像轮廓不变
  • 双边滤波器之所以能够做到在平滑去噪的同时还能够很好的保存边缘(Edge Preserve),是由于其滤波器的核由两个函数生成:空间域核值域核
    [OpenCV] 09-模糊图像_第7张图片
  • 空域权重衡量的是两点之间的距离,距离越远权重越低;
  • 值域权重衡量的是两点之间的像素值相似程度,越相似权重越大。
  • 双边滤波学习资料博客:https://blog.csdn.net/guyuealian/article/details/82660826

六 相关API

1-均值模糊

  • blur(Mat src, Mat dst, Size(xradius, yradius), Point(-1,-1));
    //Point(-1,-1)代表待处理像素在中心kernel

2-高斯模糊

  • GaussianBlur(Mat src, Mat dst, Size(11, 11), sigmax, sigmay);
    //其中Size(x, y), x, y 必须是正数而且是奇数
    // 一般椒盐噪声比较多用中值模糊,若其它噪声比较多,就用均值模糊,两者都有,就用高斯模糊

代码演示:

#include 
#include 

using namespace std;
using namespace cv;

int main(char argc,char** argv)
{
	Mat myImage = imread("women.jpg", 1);
	if (!myImage.data)
	{
		cout << "couldn't load image..." << endl;
		return -1;
	}
	char inputTitle[] = "input demo";
	char outputTitle1[] = "blur demo";
	char outputTitle2[] = "gaussianblur demo";
	namedWindow(inputTitle, WINDOW_AUTOSIZE);
	imshow(inputTitle, myImage);
	Mat im_blur;
	blur(myImage, im_blur, Size(5, 5), Point(-1, -1));   //均值滤波 
	Mat im_gaussianblur;
	GaussianBlur(myImage,im_gaussianblur,Size(5,5),11,11); //高斯滤波
	namedWindow(outputTitle1, WINDOW_AUTOSIZE);
	imshow(outputTitle1, im_blur);
	namedWindow(outputTitle2, WINDOW_AUTOSIZE);
	imshow(outputTitle2, im_gaussianblur);
	waitKey(0);
	return 0;
}

3-中值滤波

  • dianBlur(Mat src, Mat dest, ksize);
    //中值模糊的ksize大小必须是大于1而且必须是奇数。

4-双边滤波

  • bilateralFilter(src, dest, d=15,150, 3);

//15 –d 计算的半径,半径之内的像数都会被纳入计算,如果提供-1 则根据sigma space参数取值
//150 – sigma color 颜色空间过滤器的sigma值,这个参数的值越大,表明该像素邻域内有越宽广的颜色会被混合到一起,产生较大的半相等颜色区域。决定多少差值之内的像素会被计算
//3 – sigma space 坐标空间中滤波器的sigma值,如果该值较大,则意味着越远的像素将相互影响,从而使更大的区域中足够相似的颜色获取相同的颜色。当d>0时,d指定了邻域大小且与sigmaSpace无关,否则d正比于sigmaSpace. 如果d的值大于0则声明无效,否则根据它来计算d值


上图分别为原图、均值滤波处理、双边滤波处理
对比发现双边滤波保留了图像轮廓。

代码演示:

#include 
#include 

using namespace std;
using namespace cv;

 int main(char argc,char** argv)
{
	Mat myImage = imread("Scarlett Johansson.jpg", 1);
	if (!myImage.data)
	{
		cout << "couldn't load image..." << endl;
		return -1;
	}
	char inputTitle[] = "input demo";
	char outputTitle1[] = "medianBlur demo";
	char outputTitle2[] = "bilateralFilter demo";
	namedWindow(inputTitle, WINDOW_AUTOSIZE);
	imshow(inputTitle, myImage);
	Mat im_medianBlur;
	medianBlur(myImage, im_medianBlur,7);  //中值滤波 
	Mat im_bilateralFilter;
	bilateralFilter(myImage, im_bilateralFilter,7, 100,3); //双边模糊
	namedWindow(outputTitle1, WINDOW_AUTOSIZE);
	imshow(outputTitle1, im_medianBlur);
	namedWindow(outputTitle2, WINDOW_AUTOSIZE);
	imshow(outputTitle2, im_bilateralFilter);
	waitKey(0);
	return 0;
}

对比发现双边滤波较中值滤波保留了图像轮廓。
在双边滤波的基础上进行掩膜操作提高对比度:

Mat im_bilateralFilter;
bilateralFilter(myImage, im_bilateralFilter, 5, 100,3); //双边模糊
Mat resultImage;
Mat kernel = (Mat_<int>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1,
0);
filter2D(im_bilateralFilter, resultImage,
im_bilateralFilter.depth(), kernel, Point(-1, -1));

【完】

备注:以上内容转载笔者早期OneNote笔记,多为基础知识记录,比较简陋。
后记:笔者才疏学浅,如有错误,望指出。

你可能感兴趣的:(机器视觉,opencv)