【从零学习OpenCV 4】图像中添加椒盐噪声

重磅干货,第一时间送达

经过几个月的努力,小白终于完成了市面上第一本OpenCV 4入门书籍《从零学习OpenCV 4》。为了更让小伙伴更早的了解最新版的OpenCV 4,小白与出版社沟通,提前在公众号上连载部分内容,请持续关注小白。

椒盐噪声又被称作脉冲噪声,它会随机改变图像中的像素值,是由相机成像、图像传输、解码处理等过程产生的黑白相间的亮暗点噪声,其样子就像在图像上随机的撒上一些盐粒和黑椒粒,因此被称为椒盐噪声。目前为止OpenCV 4中没有提供专门用于为图像添加椒盐噪声的函数,需要使用者根据自己需求去编写生成椒盐噪声的程序,本小节将会带领读者一起实现在图像中添加椒盐噪声。

考虑到椒盐噪声会随机产生在图像中的任何一个位置,因此对于椒盐噪声的生成需要使用到OpenCV 4中能够产生随机数的函数rand(),为了能够生成不同数据类型的随机数,该函数拥有多种演变形式,在代码清单5-3中给出了这几种形式的函数原型。

代码清单5-3 随机数函数原型
1.  int cvflann::rand()
2.  
3.  double cvflann::rand_double(double  high = 1.0,
4.                                    double  low = 0 
5.                                    )
6.  
7.  int cvflann::rand_int(int  high = RAND_MAX,
8.                            int  low = 0 
9.                            )
  • high:输出随机数的最大值

  • low:输出随机数的最小值

这三个函数都可以用来生成随机数,区别在于第一个函数rand()不需要输入任何的参数,返回的随机数为int类型;第二个函数rand_double()需要输入随机数的上下边界,默认状态下生成的随机数在0到1之间,返回的随机数为double类型;第三个函数rand_int()也需要输入随机数的上下边界,不同的是该函数默认状态下的最大值为RAND_MAX,这是一个由系统定义的宏变量,在笔者的计算机中这个变量表示的是整数32767,该函数会返回的随机数为int类型。这三个函数的功能和使用方式上都比较简单,这里有个小技巧,rand()函数虽然没有给出随机数的取值范围,但是可以采用求取余数的方式来实现对随机数范围的设置,例如使用rand()函数随机生成一个0到100之间的整数,可以使用“int a = rand()%100”语句来实现,因为无论任何数除以100后的余数一定在0到100之间。

注意

该函数与之前所有的函数不相同之处在于该函数并不在cv的命名空间中,而是在cvflann类中,因此在使用的时候一定要在函数前添加前缀,如cvflann::rand()。有些读者在使用rand()函数时不添加cvflann命名空间的前缀也可以使用,是因为该函数不仅在OpenCV 4中有,在stdlib.h头文件中同样有这个函数,只有在函数前面添加了命名空间前缀时使用的才是OpenCV 4中的随机数生成函数。

了解随机函数之后,在图像中添加椒盐噪声大致分为以下4个步骤

Step1:确定添加椒盐噪声的位置。根据椒盐噪声会随机出现在图像中任何一个位置的特性,我们可以通过随机数函数生成两个随机数,分别用于确定椒盐噪声产生的行和列。

Step2:确定噪声的种类。不仅椒盐噪声的位置是随机的,噪声点是黑色的还是白色的也是随机的,因此可以再次生成的随机数,通过判断随机数的奇偶性确定该像素是黑色噪声点还是白色噪声点。

Step3:修改图像像素灰度值。判断图像通道数,通道数不同的图像中像素表示白色的方式也不相同。也可以根据需求只改变多通道图像中某一个通道的数值。

Step4:得到含有椒盐噪声的图像。

依照上述思想,在代码清单5-4中给出在图像中添加椒盐噪声的示例程序,程序中判断了输入图像是灰度图还是彩色图,但是没有对彩色图像的单一颜色通道产生椒盐噪声。如果需要对某一通道产生椒盐噪声,只需要单独处理彩色图像每个通道即可。程序在图像中添加椒盐噪声的结果如图5-6、图5-7所示,由于椒盐噪声是随机添加的,因此每次运行结果会有所差异。

代码清单5-4 mySaltAndPepper.cpp图像中添加椒盐噪声
1.  #include <opencv2\opencv.hpp>
2.  #include <iostream>
3.  
4.  using namespace cv;
5.  using namespace std;
6.  
7.  //盐噪声函数
8.  void saltAndPepper(cv::Mat image, int n)
9. {
10.    for (int k = 0; k<n / 2; k++)
11.    {
12.      //随机确定图像中位置
13.      int i, j;
14.      i = std::rand() % image.cols; //取余数运算,保证在图像的列数内
15.      j = std::rand() % image.rows; //取余数运算,保证在图像的行数内
16.      int write_black = std::rand() % 2; //判定为白色噪声还是黑色噪声的变量
17.      if (write_black == 0) //添加白色噪声
18.      {
19.        if (image.type() == CV_8UC1) //处理灰度图像
20.        {
21.          image.at<uchar>(j, i) = 255; //白色噪声
22.        }
23.        else if (image.type() == CV_8UC3) //处理彩色图像
24.        {
25.          image.at< Vec3b>(j, i)[0] = 255; //Vec3b为opencv定义的3个值的向量类型
26.          image.at<Vec3b>(j, i)[1] = 255; //[]指定通道,B:0,G:1,R:2
27.          image.at<Vec3b>(j, i)[2] = 255;
28.        }
29.      }
30.      else  //添加黑色噪声
31.      {
32.        if (image.type() == CV_8UC1)
33.        {
34.          image.at<uchar>(j, i) = 0;
35.        }
36.        else if (image.type() == CV_8UC3)
37.        {
38.          image.at< Vec3b>(j, i)[0] = 0; //Vec3b为opencv定义的3个值的向量类型
39.          image.at<Vec3b>(j, i)[1] = 0; //[]指定通道,B:0,G:1,R:2
40.          image.at<Vec3b>(j, i)[2] = 0;
41.        }
42.      }
43.  
44.    }
45.  }
46.  
47.  int main()
48. {
49.    Mat lena = imread("lena.png");
50.    Mat equalLena = imread("equalLena.png", IMREAD_ANYDEPTH);
51.    if (lena.empty()||equalLena.empty())
52.    {
53.      cout << "请确认图像文件名称是否正确" << endl;
54.      return -1;
55.    }
56.    imshow("lena原图", lena);
57.    imshow("equalLena原图", equalLena);
58.    saltAndPepper(lena, 10000); //彩色图像添加椒盐噪声
59.    saltAndPepper(equalLena, 10000); //灰度图像添加椒盐噪声
60.    imshow("lena添加噪声", lena);
61.    imshow("equalLena添加噪声", equalLena);
62.    waitKey(0);
63.    return 0;
64.  }

图5-6 mySaltAndPepper.cpp程序中灰度图添加椒盐噪声结果

图5-7 mySaltAndPepper.cpp程序中彩色图添加椒盐噪声结果

(0)

相关推荐

  • Excel中-如何一秒填满100个单元格?

    今天我遇到了这样一个需求,给别人演示的时候需要一些数据,临时编太慢,是不是能有一个函数很快的生成一些随机数,满足当下演示的需求呢?比如下图,如何一秒钟填满空白处的数据? 一秒如何填满这张表? 答案:当 ...

  • python+opencv图像处理(二十九)

    高斯滤波 迟到的节日祝福......  粽子节快乐,纪念伟大的屈原先生 (图片来源于网络) 高斯滤波是一种线性平滑滤波,对于消除高斯噪声有很好的效果,对于服从正态分布的噪声非常有效. 高斯滤波就是对整 ...

  • 「函数010」- EXCEL如何随机打乱数据,不重复随机数来帮忙!

    今天我们继续学习我们函数实战系列!一个不小心,我们已经更新9期了,今天就是第十期!具体讲点啥? 第十期-生成随机不重复数据! 顺势我们把相关的随机函数也学习一下,一举两得! 在EXCEL的中,要生成随 ...

  • excel怎样生成随机数

    在写这篇教程之前,我要吟诗一首,啊! 世界仓管千千万,唯有我是大混蛋: 仓库管好还不算,还写教程来骗钱. 辛辛苦苦大半年,粉丝还没到一千: 啥事做着都很难,甩开膀子加油干. 吟完诗了,该写教程啦! 在 ...

  • 【从零学习OpenCV 4】图像中添加高斯噪声

    重磅干货,第一时间送达 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4入门书籍<从零学习OpenCV 4>.为了更让小伙伴更早的了解最新版的OpenCV 4,小白与出版社沟通 ...

  • 【从零学习OpenCV 4】中值滤波

    重磅干货,第一时间送达 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4入门书籍<OpenCV 4开发详解>.为了更让小伙伴更早的了解最新版的OpenCV 4,小白与出版社沟通 ...

  • 【从零学习OpenCV】图像的保存&视频的保存

    重磅干货,第一时间送达 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4入门书籍<从零学习OpenCV 4>.为了更让小伙伴更早的了解最新版的OpenCV 4,小白与出版社沟通 ...

  • 【从零学习OpenCV 4】图像修复

    重磅干货,第一时间送达 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4入门书籍<OpenCV 4开发详解>.为了更让小伙伴更早的了解最新版的OpenCV 4,小白与出版社沟通 ...

  • 【从零学习OpenCV 4】分割图像——Mean-Shift分割算法

    重磅干货,第一时间送达 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4入门书籍<从零学习OpenCV 4>.为了更让小伙伴更早的了解最新版的OpenCV 4,小白与出版社沟通 ...

  • 【从零学习OpenCV 4】分割图像——Grabcut图像分割

    重磅干货,第一时间送达 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4入门书籍<OpenCV 4开发详解>.为了更让小伙伴更早的了解最新版的OpenCV 4,小白与出版社沟通 ...

  • 【从零学习OpenCV 4】分割图像——分水岭法

    重磅干货,第一时间送达 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4入门书籍<OpenCV 4开发详解>.为了更让小伙伴更早的了解最新版的OpenCV 4,小白与出版社沟通 ...

  • 【从零学习OpenCV 4】图像矩的计算与应用

    重磅干货,第一时间送达 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4入门书籍<从零学习OpenCV 4>.为了更让小伙伴更早的了解最新版的OpenCV 4,小白与出版社沟通 ...

  • 【从零学习OpenCV 4】图像膨胀

    重磅干货,第一时间送达 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4入门书籍<OpenCV 4开发详解>.为了更让小伙伴更早的了解最新版的OpenCV 4,小白与出版社沟通 ...