【OpenCV】给图像加入噪声
图像噪声使图像在获取或是传输过程中收到随机信号干扰,妨碍人们对图像理解及分析处理的信号。非常多时候将图像噪声看做多维随机过程,因而描写叙述噪声的方法全然能够借用随机过程的描写叙述,也就是使用随机过程的描写叙述,也就是用它的高绿分布函数和概率密度分布函数。图像噪声的产生来自图像获取中的环境条件和传感元器件自身的质量,图像在传输过程中产生图像噪声的主要因素是所用的传输信道收到了噪声的污染。
以下简介两种图像噪声。即椒盐噪声和高斯噪声。
1.椒盐噪声
椒盐噪声也称为脉冲噪声,是图像中常常见到的一种噪声,它是一种随机出现的白点或者黑点,可能是亮的区域有黑色像素或是在暗的区域有白色像素(或是两者皆有)。
盐和胡椒噪声的成因可能是影像讯号受到突如其来的强烈干扰而产生、类比数位转换器或位元传输错误等。比如失效的感应器导致像素值为最小值。饱和的感应器导致像素值为最大值。
图像模拟加入椒盐噪声是通过随机获取像素点并设置为高亮度点和低灰度点来实现的
图像加入椒盐噪声的程序例如以下:
//利用程序给原图像添加椒盐噪声 //图象模拟加入椒盐噪声是通过随机获取像素点斌那个设置为高亮度点来实现的 #include <cstdlib> #include <iostream> #include <opencv2\core\core.hpp> #include <opencv2\highgui\highgui.hpp> #include <opencv2\imgproc\imgproc.hpp> using namespace cv; using namespace std; Mat addSaltNoise(const Mat srcImage, int n); int main() { Mat srcImage = imread("2345.jpg"); if (!srcImage.data) { cout << "读入图像有误!" << endl; system("pause"); return -1; } imshow("原图像", srcImage); Mat dstImage = addSaltNoise(srcImage, 3000); imshow("加入椒盐噪声的图像", dstImage); //存储图像 imwrite("salt_pepper_Image.jpg", dstImage); waitKey(); return 0; } Mat addSaltNoise(const Mat srcImage, int n) { Mat dstImage = srcImage.clone(); for (int k = 0; k < n; k++) { //随机取值行列 int i = rand() % dstImage.rows; int j = rand() % dstImage.cols; //图像通道判定 if (dstImage.channels() == 1) { dstImage.at<uchar>(i, j) = 255; //盐噪声 } else { dstImage.at<Vec3b>(i, j)[0] = 255; dstImage.at<Vec3b>(i, j)[1] = 255; dstImage.at<Vec3b>(i, j)[2] = 255; } } for (int k = 0; k < n; k++) { //随机取值行列 int i = rand() % dstImage.rows; int j = rand() % dstImage.cols; //图像通道判定 if (dstImage.channels() == 1) { dstImage.at<uchar>(i, j) = 0; //椒噪声 } else { dstImage.at<Vec3b>(i, j)[0] = 0; dstImage.at<Vec3b>(i, j)[1] = 0; dstImage.at<Vec3b>(i, j)[2] = 0; } } return dstImage; }
运行程序后,输出的效果例如以下:
2.高斯噪声
高斯噪声是指高绿密度函数服从高斯分布的一类噪声。特别的,假设一个噪声,它的幅度分布服从高斯分布,而它的功率谱密度有事均匀分布的,则称这个噪声为高斯白噪声。
高斯白噪声二阶矩不相关。一阶矩为常数,是指先后信号在时间上的相关性。高斯噪声包含热噪声和三里噪声。
高斯噪声万有由它的事变平均值和两瞬时的协方差函数来确定,若噪声是平稳的。则平均值与时间无关,而协方差函数则变成仅和所考虑的两瞬时之差有关的相关函数。在意义上它等同于功率谱密度。高斯早生能够用大量独立的脉冲产生,从而在不论什么有限时间间隔内。这些脉冲中的每个买充值与全部脉冲值得总和相比都可忽略不计。
依据Box-Muller变换原理,建设随机变量U1、U2来自独立的处于(0,1)之间的均匀分布,则经过以下两个式子产生的随机变量Z0。Z1服从标准高斯分布。
上式中Z0,Z1满足正态分布,当中均值为0,方差为1,变量U1和U2能够改动为下式:
给图像加入高斯噪声的程序例如以下:
//给图像加入高斯噪声 #include <cmath> #include <limits> #include <cstdlib> #include <iostream> #include <opencv2\core\core.hpp> #include <opencv2\highgui\highgui.hpp> using namespace cv; using namespace std; double generateGaussianNoise(double m, double sigma); Mat addGaussianNoise(Mat &srcImag); int main() { Mat srcImage = imread("2345.jpg"); if (!srcImage.data) { cout << "读入图片错误!" << endl; system("pause"); return -1; } imshow("原图像", srcImage); Mat dstImage = addGaussianNoise(srcImage); imshow("加入高斯噪声后的图像", dstImage); waitKey(); return 0; } //生成高斯噪声 double generateGaussianNoise(double mu, double sigma) { //定义小值 const double epsilon = numeric_limits<double>::min(); static double z0, z1; static bool flag = false; flag = !flag; //flag为假构造高斯随机变量X if (!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为真构造高斯随机变量 z0 = 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; } //为图像加入高斯噪声 Mat addGaussianNoise(Mat &srcImag) { Mat dstImage = srcImag.clone(); int channels = dstImage.channels(); int rowsNumber = dstImage.rows; int colsNumber = dstImage.cols*channels; //推断图像的连续性 if (dstImage.isContinuous()) { colsNumber *= rowsNumber; rowsNumber = 1; } for (int i = 0; i < rowsNumber; i++) { for (int j = 0; j < colsNumber; j++) { //加入高斯噪声 int val = dstImage.ptr<uchar>(i)[j] + generateGaussianNoise(2, 0.8) * 32; if (val < 0) val = 0; if (val>255) val = 255; dstImage.ptr<uchar>(i)[j] = (uchar)val; } } return dstImage; }
程序运行后的效果图例如以下: