OpenCV4学习笔记(13)——图像添加椒盐、高斯噪声及去噪

本次要整理的内容是基于OpenCV4学习笔记(12)中的三种模糊方式,首先为一张图像添加噪声,分别添加椒盐噪声和高斯噪声,然后通过均值模糊、高斯模糊和中值滤波来分别对比这三种滤波方式对不同种类噪声的抑制效果如何。最后再记录一种新的滤波方式:非局部均值滤波。

  • 对图像添加噪声
    噪声主要有椒盐噪声和高斯噪声。其中椒盐噪声就是在图像上随机分布的一些黑白噪声点,椒噪声就是黑色噪声点,盐噪声就是白色噪声点,可以想象一下老式电视在信号不好的时候出现的哗哗哗的雪花,感觉那就是非常严重的椒盐噪声(我也不确定是不是哈,毕竟咱受年龄所限,也没见识过真正的老式电视。。。)下面给出添加椒盐噪声的代码实现:
	RNG rng(0);			//创建一个随机数对象;可输入随机数种子
	int height = image.rows;
	int width = image.cols;
	Mat salf_pepper_noise_image = image.clone();
	for (int i = 0; i < 10000; i++)
	{
			//随机生成噪声点的坐标
			int x = rng.uniform(0, width);
			int y = rng.uniform(0, height);
			//让黑白两种噪点数量均衡
			if (0 == i % 2)
			{
				salf_pepper_noise_image.at<Vec3b>(y, x) = Vec3b(255, 255, 255);			//(y,x)对应(row, col)
			}
			else
			{
				salf_pepper_noise_image.at<Vec3b>(y, x) = Vec3b(0, 0, 0);
			}
	}
	imshow("salf_pepper_noise_image", salf_pepper_noise_image);

代码实现还是比较简单的,利用一个随机数对象来分别随机生成噪声点的x、y坐标,然后就对图像中的该点处的像素值置为0或255,分别代表椒、盐噪声。为了使椒盐两种噪声数量均衡,所以对添加数量做了个取余操作来判断是不是偶数个噪声点,如果是就为盐噪声,不是就为椒噪声。
同时这里有个小细节:0 == i % 2,就是在使用到==这个运算符的时候把常数项放到左边,避免因为少打了个 = 号而变成了赋值式,那就会引发错误而且还难以发现。
下面再看高斯噪声的添加。高斯噪声的出现一般是不可避免的,一般会在数码相机的图像采集(acquisition)阶段产生高斯噪声,物理、电、光等各种信号都可能导致产生高斯分布噪声。OpenCV中有一个API可以实现对图像添加高斯噪声,代码如下:

	Mat gaussian_noise_image = image.clone();
	//定义一张空白图像,用来生成高斯噪声
	Mat noise = Mat::zeros(image.size(), image.type());
	randn(noise, (10, 100, 10), (30, 30, 30));
	//将噪声图和原图相加
	add(image, noise, gaussian_noise_image, Mat(), -1);
	imshow("gaussian_noise_image", gaussian_noise_image);
	imshow("image", image);

这行代码randn(noise, (10, 100, 10), (30, 30, 30))就实现高斯噪声的添加,第二和第三个参数分别为三通道的均值(mean)和方差(stddev),如果mean和stddev各只写一个则默认三通道具有相同的均值和方差。
最后生成的椒盐噪声图和高斯噪声图,相对于原图效果如下:
原图
左:椒盐噪声;右:高斯噪声

  • 滤波降噪处理
    对图像添加完噪声后,我们下面就分别使用均值滤波、高斯滤波、中值滤波来实现对噪声的过滤,并对比三个滤波方式对椒盐噪声和高斯噪声的抑制效果。(PS:模糊其实是一种主观视觉上的说法吧,其实是进行了低通滤波,将高频的细节和噪声抑制住,只让低频的图像大体内容保存下来,而在视觉上就造成了模糊的感觉;个人觉得均值滤波和均值模糊其实指代的是同样的操作,只是一个是从客观角度的名称,一个是主观角度的名称)
	Mat blur_salf_pepper_image;
	Mat blur_gaussian_image;
	Mat median_salf_pepper_image;
	Mat median_gaussian_image;
	Mat gaussian_gaussian_image;
	Mat gaussian_salf_pepper_image;
	Mat Denoise_salf_pepper_image;
	Mat Denoise_gaussian_image;

	//均值滤波去噪
	blur(salf_pepper_noise_image, blur_salf_pepper_image, Size(3, 3));
	blur(gaussian_noise_image, blur_gaussian_image, Size(3, 3));
	imshow("blur_salf_pepper_image", blur_salf_pepper_image);
	imshow("blur_gaussian_image", blur_gaussian_image);

	//高斯滤波去噪,针对高斯噪声
	GaussianBlur(salf_pepper_noise_image, gaussian_salf_pepper_image, Size(), 1);
	GaussianBlur(gaussian_noise_image, gaussian_gaussian_image, Size(), 1);
	imshow("gaussian_salf_pepper_image", gaussian_salf_pepper_image);
	imshow("gaussian_gaussian_image", gaussian_gaussian_image);

	//中值滤波去噪,针对椒盐噪声
	medianBlur(salf_pepper_noise_image, median_salf_pepper_image, 3);
	medianBlur(gaussian_noise_image, median_gaussian_image, 3);
	imshow("median_salf_pepper_image", median_salf_pepper_image);
	imshow("median_gaussian_image", median_gaussian_image);

我们对上面得到的椒盐噪声图和高斯噪声图分别进行处理后,三种滤波操作分别得到下面三幅对比图像(左边为处理后的椒盐噪声图,右边为处理后的高斯噪声图):
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
进行逐一分析,可以看出:
(1)均值滤波对高斯噪声有一定的抑制效果,但效果不是很好;而对于椒盐噪声,就只是将噪声的强度略微削弱,仍然存在很明显的椒盐噪声。所以均值滤波对噪声的抑制效果并不是特别的好。
(2)高斯滤波对于椒盐噪声的抑制效果,感觉和均值滤波是半斤八两谁也笑话不了谁,都仍然能看到明显的椒盐噪声;但是对于高斯噪声的抑制效果,高斯滤波是比较好一些的,当放大图片观察的时候,会发现相比原高斯噪声图像,处理后的图像少去了非常多密密麻麻的小点,不仔细看是看不出来的。
(3)中值滤波就很明显了,十足的偏科。对于椒盐噪声的效果非常的好,经过处理后几乎看不出原有的椒盐噪声的痕迹了;但是对于高斯噪声,经过处理后也几乎看不出原有的高斯噪声被抑制的痕迹。。。可见当图像存在椒盐噪声的时候,中值滤波肯定是首选操作。

  • 非局部均值滤波
    最后记录一种对于高斯噪声处理效果非常好的滤波器:非局部均值滤波。非局部均值滤波对于噪声的抑制效果好,但是缺点是处理速度慢,而且是针对于抑制高斯噪声,对椒盐噪声几乎无效果(不慌,有中值滤波撑腰)。
    与均值滤波、中值滤波等利用图像局部信息来滤波(也就是只利用卷积窗口里的信息进行滤波)的算法不同的是,非局部均值滤波在理论上利用了整幅图像来进行降噪,但是处理速度很慢,实际上仍然会规定窗口来提高处理速度。
    非局部均值滤波的原理是:以图像块(patch)为单位在图像中移动,寻找相似区域,对每个区域赋予一个权重,和patch越相似的区域获得的权重越大,再对这些区域进行加权求和,最后的输出图像就能够比较好地去掉图像中存在的高斯噪声。
    实际使用时,会定义一个模板窗口和一个搜索窗口,模板窗口大概为搜索窗口的三分之一。模板窗口在搜索窗口中移动,计算图像中其他区域跟中心位置patch的相似度,相似度越高,得到的权重越大。最后将这些相似的像素值根据归一化之后的权重加权求和,得到的就是去噪之后的搜索窗口内的图像区域。最后搜索窗口在整幅图像中移动,分别得到所有区域的输出结果,就能得到一张完整的输出降噪图像。OpenCV中提供了两个专门的API进行非局部均值滤波操作,代码如下:
	fastNlMeansDenoisingColored(salf_pepper_noise_image, Denoise_salf_pepper_image, 10, 10, 7, 21);
	fastNlMeansDenoisingColored(gaussian_noise_image, Denoise_gaussian_image, 10, 10, 7, 21);	
	imshow("Denoise_salf_pepper_image", Denoise_salf_pepper_image);
	imshow("Denoise_gaussian_image", Denoise_gaussian_image);

代码fastNlMeansDenoisingColored(salf_pepper_noise_image, Denoise_salf_pepper_image, 10, 10, 7, 21)中,第一个参数是要进行处理的输入图像;第二个参数是输出图像;第四个参数h是权重衰减系数, 决定过滤器强度。h 值高可以很好的去除噪声,但也会把图像的细节抹去;第五个参数hcolor:与h相同,用于彩色图像;第六和第七个参数为模板窗口和搜索窗口的尺寸:模板窗口:搜索窗口一般取 1:3(推荐值为7:21)。
这个API是针对彩色多通道图像来处理的,还有一个APIfastNlMeansDenoising()是专门用于处理灰度图像的。
处理效果如下:
在这里插入图片描述
可以看出,非局部均值滤波对于椒盐噪声几乎是没有效果的,但是对于高斯噪声的抑制效果非常好,处理过后几乎看不出高斯噪声的踪迹。但是如果滤波器强度设置过大,就会使得图像细节被抹除掉,例如猫猫的毛发就没有那么的清晰可见,而是显得涂抹感比较重。所以参数的设置仍是需要根据具体情况来具体调试。

本次整理记录到此结束,感谢阅读~~~

PS:本人的注释比较杂,既有自己的心得体会也有网上查阅资料时摘抄下的知识内容,所以如有雷同,纯属我向前辈学习的致敬,如果有前辈觉得我的笔记内容侵犯了您的知识产权,请和我联系,我会将涉及到的博文内容删除,谢谢!

发布了36 篇原创文章 · 获赞 43 · 访问量 1813

猜你喜欢

转载自blog.csdn.net/weixin_45224869/article/details/104607748