【拜小白opencv】27-图像噪声2——高斯噪声

来源:互联网 发布:慈溪行知职高大学生 编辑:程序博客网 时间:2024/06/06 05:44

常言道“温故而知新”,写此文章就是对自己目前学习内容的小小的总结与记录。

本文力求用最简洁的语言,详细的代码将此部分内容讲解清楚,但由于博主同样是刚刚接触OpenCV,或许表达上有些瑕疵,还望读者能够指教探讨,大家共同进步。

博主机器配置为:VS2013+opencv2.4.13+Win-64bit。

若本文能给读者带来一点点启示与帮助,我就很开心了。

===========================分割线========================


1-图像噪声

  • 图像噪声是图像在获取或传输过程中收到随机信号干扰,妨碍人们对图像理解及分析处理的信号
  • 图像噪声的产生来自图像获取中的环境条件和传感元器件自身的质量,图像在传输过程中产生图像噪声的主要因素是所用的传输信道收到了噪声的污染。
  • 噪声在理论上可以定义为“不可预测,只能用概率统计方法来认识的随机误差”。因此将图像噪声看成是多维随机过程是合适的,因而描述噪声的方法完全可以借用随机过程的描述,即用其概率分布函数概率密度分布函数

常见的衡量信号噪声大小的方法是计算信噪比(SIGNAL-NOISE RATIO),对于图像f(x,y),图像的信噪比定义为下式:
                         
其中v(i,j)是噪声,在图像处理场景中噪声是多种多样的,本节介绍高斯噪声。

========================分割线=======================

2-高斯噪声

  • 高斯噪声是指它的概率密度函数服从高斯分布(即正态分布)的一类噪声。
  • 特别的,如果一个噪声,它的幅度分布服从高斯分布,而它的功率谱密度又是均匀分布的,则称这个噪声为高斯白噪声。高斯白噪声的二阶矩不相关,一阶矩为常数,是指先后信号在时间上的相关性。高斯白噪声包括热噪声散粒噪声
  • 高斯噪声完全由它的时变平均值两瞬时协方差函数来确定,若噪声是平稳的,则平均值与时间无关,而协方差函数则变成仅和所考虑的两瞬时之差有关的相关函数,在意义上它等同于功率谱密度。
  • 高斯噪声可以由大量独立的脉冲产生,从而在任何有限时间间隔内,这些脉冲中的每一个脉冲值与所有脉冲值的总和相比都可忽略不计。
  • 常见的高斯噪声包括起伏噪声、宇宙噪声、热噪声和散粒噪声等等。除常用抑制噪声的方法外,对高斯噪声的抑制方法常常采用数理统计方法

根据Box-Muller变换原理,建设随机变量U1、U2来自独立的处于(0,1)之间的均匀分布,则经过下面两个式子产生的随机变量Z0,Z1服从标准高斯分布:
上式中Z0、Z1满足正态分布,其中均值为0,方差为1,变量U1和U2可修改为下式:
=========================分割线================================
高斯噪声与椒盐噪声比较
椒盐噪声是出现在随机位置、噪点深度基本固定的噪声;高斯噪声与其相反,是几乎每个点上都出现噪声、噪点深度随机的噪声。
=========================分割线=================================

3-代码演示

/*给图像添加高斯噪声*/#include <opencv2/core/core.hpp>              #include <opencv2/highgui/highgui.hpp>            #include <iostream>#include <cstdlib> #include <cmath>#include <limits>using namespace std;using namespace cv;//--------------【全局函数声明部分】------------ Mat addGuassianNoise(Mat& srcImage);//添加高斯噪声函数double generateGaussianNoise(double mu, double sigma);//生成高斯噪声//---------------【主函数】----------------------  int main(){//------------【1】读取源图像并检查图像是否读取成功------------ Mat srcImage = imread("D:\\OutPutResult\\ImageTest\\dog12.jpg");if (!srcImage.data){cout << "读取图片错误,请重新输入正确路径!\n";system("pause");return -1;}imshow("【源图像】", srcImage);//------------【2】给图像添加高斯噪声----------------------  Mat dstImage = addGuassianNoise(srcImage);imshow("【高斯噪声图像】", dstImage);waitKey(0);return 0;}//------------【为图像添加高斯噪声】----------------Mat addGuassianNoise(Mat& srcImage){Mat resultImage = srcImage.clone(); // 克隆一副与源图像尺寸类型一样的图像int channels = resultImage.channels();//获取图像的通道int nRows = resultImage.rows;//图像的行数  int nCols = resultImage.cols*channels;//图像的总列数 //判断图像的连续性if (resultImage.isContinuous()) //判断矩阵是否连续,若连续,我们相当于只需要遍历一个一维数组{nCols *= nRows;nRows = 1;}//遍历图像中的像素for (int i = 0; i < nRows; ++i){for (int j = 0; j < nCols; ++j){//添加高斯噪声int val = resultImage.ptr<uchar>(i)[j] + generateGaussianNoise(2, 0.8) * 32;if (val < 0)val = 0;if (val > 255)val = 255;resultImage.ptr<uchar>(i)[j] = (uchar)val;}}return resultImage;}//-------------【生成高斯噪声】---------  double generateGaussianNoise(double mu, double sigma){//定义一个特别小的值  const double epsilon = std::numeric_limits<double>::min();//返回目标数据类型能表示的最逼近1的正数和1的差的绝对值static double z0, z1;static bool flag = false;flag = !flag;//flag为假,构造高斯随机变量Xif (!flag){return z1*sigma + mu;}double u1, u2;//构造随机变量do{u1 = rand()*(1.0 / RAND_MAX);u2 = rand()*(1.0 / RAND_MAX);} while (u1 <= epsilon);//flag为真,构造高斯随机变量Xz0 = sqrt(-2.0*log(u1))*cos(2 * CV_PI*u2);z1 = sqrt(-2.0*log(u1))*sin(2 * CV_PI*u2);return z0*sigma + mu;}
===================分割线=====================

4-显示结果


=====================分割线================

5-程序说明

可以发现,与上一节椒盐噪声相比,经过高斯噪声的图像,画面不清晰,画质很不好。这是因为,椒盐噪声是出现在随机位置、噪点深度基本固定的噪声;高斯噪声与其相反,是几乎每个点上都出现噪声、噪点深度随机的噪声。

==================END==============

原创粉丝点击