【从零学习OpenCV 4】图像中添加高斯噪声
重磅干货,第一时间送达
经过几个月的努力,小白终于完成了市面上第一本OpenCV 4入门书籍《从零学习OpenCV 4》。为了更让小伙伴更早的了解最新版的OpenCV 4,小白与出版社沟通,提前在公众号上连载部分内容,请持续关注小白。
OpenCV 4中同样没有专门为图像添加高斯噪声的函数,对照在图像中添加椒盐噪声的过程,我们可以根据需求利用能够产生随机数的函数来完成在图像中添加高斯噪声的任务。在OpenCV 4中提供了fill()函数可以产生均匀分布或者高斯分布(正态分布)的随机数,我们可以利用该函数产生符合高斯分布的随机数,之后在图像中加入这些随机数即可,我们首先了解该函数的使用方式,该函数的函数原型在代码清单5-5中给出。
代码清单5-5 fill()函数原型
1. void cv::RNG::fill(InputOutputArray mat,
2. int distType,
3. InputArray a,
4. InputArray b,
5. bool saturateRange = false
6. )
mat:用于存放随机数的矩阵,目前只支持低于5通道的矩阵。
distType:随机数分布形式选择标志,目前生成的随机数支持均匀分布(RNG::UNIFORM,0)和高斯分布(RNG::NORMAL,1)。
a:确定分布规律的参数。当选择均匀分布时,该参数表示均匀分布的最小下限;当选择高斯分布时,该参数表示高斯分布的均值。
b:确定分布规律的参数。当选择均匀分布时,该参数表示均匀分布的最大上限;当选择高斯分布时,该参数表示高斯分布的标准差。
saturateRange:预饱和标志,仅用于均匀分布。
该函数用于生成指定分布形式的随机数填充矩阵,可以生成符合均匀分布的随机数和符合高斯分布随机数。函数的第一个参数输入用于存储生成随机数的矩阵,但是矩阵的通道数必须小于等于4。第二个参数是选择随机数分布形式的标志,该函数目前只支持两种分布形式,分别是均匀分布(RNG::UNIFORM,简记0)和高斯分布(RNG::NORMAL,简记1)。函数的第三个和第四个参数为确定随机数分布规律的参数,第三个参数在均匀分布时表示均匀分布的最小下限,在高斯分布时表示高斯分布的均值;第四个参数在均匀分布时表示均匀分布的最大上限,在高斯分布时表示高斯分布的标准差。最后一个参数是预饱和标志,仅用于均匀分布,我们使用其默认式即可。需要注意的是该函数属于OpenCV 4的RNG类,是一个非静态成员函数,因此在使用的时候不能像使用正常函数一样的直接使用,而需要首先创建一个RNG类的变量,之后通过访问这个变量中函数进行调用这个函数,具体使用方式在代码清单5-6中给出。
代码清单5-6 RNG::fill()函数的使用
1. cv::RNG rng;
2. rng.fill(mat, RNG::NORMAL, 10, 20);
在图像中添加高斯噪声大致分为以下4个步骤:
Step1:首先需要创建一个与图像尺寸、数据类型以及通道数相同的Mat类变量.
Step2:通过调用fill()函数在Mat类变量中产生符合高斯分布的随机数。
Step3:将原图像和含有高斯分布的随机数矩阵相加。
Step4:得到添加高斯噪声之后的图像。
依照上述思想,在代码清单5-7中给出了在图像中添加高斯噪声的示例程序,程序实现了对灰度图像和彩色图像添加高斯噪声,在图像中添加高斯噪声的结果如图5-8、图5-9所示,由于高斯噪声是随机生成的,因此每次运行结果会有差异。
代码清单5-7 myGaussNoise.cpp图像中添加高斯噪声
1. #include <opencv2\opencv.hpp>
2. #include <iostream>
3.
4. using namespace cv;
5. using namespace std;
6.
7. int main()
8. {
9. Mat lena = imread("lena.png");
10. Mat equalLena = imread("equalLena.png", IMREAD_ANYDEPTH);
11. if (lena.empty()||equalLena.empty())
12. {
13. cout << "请确认图像文件名称是否正确" << endl;
14. return -1;
15. }
16. //生成与原图像同尺寸、数据类型和通道数的矩阵
17. Mat lena_noise = Mat::zeros(lena.rows, lena.cols, lena.type());
18. Mat equalLena_noise = Mat::zeros(lena.rows, lena.cols, equalLena.type());
19. imshow("lena原图", lena);
20. imshow("equalLena原图", equalLena);
21. RNG rng; //创建一个RNG类
22. rng.fill(lena_noise, RNG::NORMAL, 10, 20); //生成三通道的高斯分布随机数
23. rng.fill(equalLena_noise, RNG::NORMAL, 15, 30); //生成三通道的高斯分布随机数
24. imshow("三通道高斯噪声", lena_noise);
25. imshow("单通道高斯噪声", equalLena_noise);
26. lena = lena + lena_noise; //在彩色图像中添加高斯噪声
27. equalLena = equalLena + equalLena_noise; //在灰度图像中添加高斯噪声
28. //显示添加高斯噪声后的图像
29. imshow("lena添加噪声", lena);
30. imshow("equalLena添加噪声", equalLena);
31. waitKey(0);
32. return 0;
33. }
图5-8 myGaussNoise.cpp程序中灰度图添加高斯噪声结果
图5-9 myGaussNoise.cpp程序中彩色图添加高斯噪声结果