给图像添加椒盐噪声后用均值滤波和中值滤波过滤椒盐噪声的C++-OpenCV代码

椒盐噪声又被称作脉冲噪声,它会随机改变图像中的像素值,是由相机成像、图像传输、解码处理等过程产生的黑白相间的亮暗点噪声,其样子就像在图像上随机的撒上一些白盐粒和黑椒粒,因此被称为椒盐噪声。

目前为止OpenCV中没有提供专门用于为图像添加椒盐噪声的函数,需要使用者根据自己需求去编写生成椒盐噪声的程序。

在C++中,我们可以利用C++标准库中的函数srand()和函数rand()配合使用产生随机坐标,并把这些坐标置为白盐噪声点或黑椒噪声点来模拟产生椒盐噪声。

函数srand()是随机数发生器的初始化函数,函数rand()用于产生随机数。二者的使用挺简单,大家看了代码就知道怎么用了。值得说明的是,在本文提供的代码中,使用当前时间值作为随机数发生器的种子值。另外,函数rand()的范围为0至RAND_MAX,RAND_MAX的值在stdlib.h中有定义,定义如下:

#define RAND_MAX 0x7fff

0x7fff = 32767,也就是说随机数的最大值为三万二千七百六十七。

在本文的代码中,白盐噪声的BGR值为(250,250,250),椒噪声的BGR值为(10,10,10)。

再来说均值滤波和中值滤波

均值滤波:它是用某点邻域窗口内的的所有像素的平均值来代替锚点处的值。它不能很好地保护图像细节,在图像去噪的同时也破坏了图像的细节部分,从而使图像变得模糊,不能很好地去除噪声点。
中值滤波:中值滤波法是一种非线性平滑技术,它将每一像素点的灰度值设置为该点某邻域窗口内的所有像素点灰度值的中值。

OpenCV提供了函数blur()和函数medianBlur()来实现均值滤波和中值滤波。

函数blur()的原型如下:

void cv::blur(	InputArray 	src,
				OutputArray dst,
				Size 	ksize,
				Point 	anchor = Point(-1,-1),
				int 	borderType = BORDER_DEFAULT 
			)	

参数意义如下:

src---输入图像,可以是任意通道的图像,每个通道会被独立均值滤波,数据深度(数据类型)可以是CV_8U, CV_16U, CV_16S, CV_32F 或 CV_64F.

dst---输出图像,和输入图像有相同的大小和类型。

ksize---均值滤波核算子的大小。核算子的概念可以参考我写的另一篇博文,链接 https://blog.csdn.net/wenhao_ir/article/details/124173092

anchor---均值滤波窗口运算的锚点位置,默认值为窗口的中心。关于窗口运算和锚点的概念可以参考我写的另一篇博文,链接 https://blog.csdn.net/wenhao_ir/article/details/124173092

​borderType---作窗口运算时图像边界扩展方式。有关图像边界扩展方式可以参考我写的另一篇博文,链接 https://blog.csdn.net/wenhao_ir/article/details/12417798

函数medianBlur()的原型如下:

void cv::medianBlur	(	InputArray 	src,
						OutputArray dst,
						int 	ksize 
					)	

src---输入图像,可以是1通道、3通道或4通道的图像。当核算子的大小为3或5时,图像的数据类型可以为 CV_8U, CV_16U, 或CV_32F,更大的核算子时,图像的数类型只能为CV_8U。

dst---输出图像,和输入图像有相同的大小和类型。

​ksize---中值滤波核算子的大小,其大小只能为奇数。核算子的概念可以参考我写的另一篇博文,链接 https://blog.csdn.net/wenhao_ir/article/details/124173092

中值滤波函数medianBlur()没有参数​borderType,这是为什么呢?因为中值滤波是取序列的中间值作为锚点值,所以不需要扩展边界也可以有正确的运算结果,所以不需要设置参数​borderType。

​给图像添加椒盐噪声后用均值滤波和中值滤波过滤椒盐噪声的C++-OpenCV代码如下

代码中用到的图像下载链接如下:

链接:https://pan.baidu.com/s/13gKSTVRWbpkHvrTMSYtwBg?pwd=po9z 

//博主微信/QQ 2487872782
//有问题可以联系博主交流
//有图像处理需求也可联系博主
//图像处理技术交流QQ群 271891601

//OpenCV版本:3.0
//VS版本:2012

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include<opencv2/imgcodecs/imgcodecs.hpp>
#include <opencv2/imgproc/imgproc.hpp>

#include <time.h>  
#include <iostream>
 
using namespace cv;
using namespace std;
 
void ColorSalt(Mat& image, int n)//本函数为BGR图像加入白盐噪声  
{
        srand((unsigned)time(NULL)); //使用当前时间值作为随机数发生器的种子值
        for (int k = 0; k<n; k++)//将图像中n个像素随机置为白盐噪声点
        {
                int i = rand() % image.cols;
                int j = rand() % image.rows;
                image.at<Vec3b>(j, i)[0] = 250;
                image.at<Vec3b>(j, i)[1] = 250;
                image.at<Vec3b>(j, i)[2] = 250;
        }
}
 
void ColorPepper(Mat& image, int n)//本函数为BGR图像加入黑椒噪声  
{
        srand((unsigned)time(NULL));
        for (int k = 0; k<n; k++)   //将图像中n个像素随机置为黑椒噪声点
        {
                int i = rand() % image.cols;
                int j = rand() % image.rows;
                image.at<Vec3b>(j, i)[0] = 10;
                image.at<Vec3b>(j, i)[1] = 10;
                image.at<Vec3b>(j, i)[2] = 10;
        }
}
 
int main()
{
        Mat scr = imread("F:/material/images/P0005-BaoXiaofeng-02.jpg");
        
        imshow("原图像", scr);
 
        ColorSalt(scr, 3000);  //加入白盐噪声  
        ColorPepper(scr, 1000); //加入黑椒噪声  
        imshow("带噪声的图像", scr);

		Mat dst;

        medianBlur(scr, dst, 3);  //中值滤波,核算子大小为3,锚点为默认的中间点
        imshow("中值滤波结果", dst);
 
        blur(scr, dst, Size(3, 3));//均值滤波,核算子大小为3,锚点为默认的中间点
        imshow("均值滤波结果", dst);
 
        waitKey(0);
        return EXIT_SUCCESS;
}

运行结果如下图所示:

从以上运行结果可以看出,对于椒盐噪声,中值滤波的效果比均值滤波的效果好得多

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值