http://blog.csdn.net/lichengyu/article/details/31829787
通过Box-Muller变换可以产生Gaussian噪音
Box-Muller变换:假设随机变量x1, x2来自独立的处于[0,1]之间的均匀分布,则经过下面两个式子产生的随机变量z1, z2服从标准高斯分布:
实现代码(引自维基百科)
- #define TWO_PI 6.2831853071795864769252866
- double generateGaussianNoise()
- {
- static bool hasSpare = false;
- static double rand1, rand2;
- if(hasSpare)
- {
- hasSpare = false;
- return sqrt(rand1) * sin(rand2);
- }
- hasSpare = true;
- rand1 = rand() / ((double) RAND_MAX);
- if(rand1 < 1e-100) rand1 = 1e-100;
- rand1 = -2 * log(rand1);
- rand2 = (rand() / ((double) RAND_MAX)) * TWO_PI;
- return sqrt(rand1) * cos(rand2);
- }
给图片添加高斯噪音的代码:
- #include <opencv2/core/core.hpp>
- #include <opencv2/highgui/highgui.hpp>
- #include <iostream>
- using namespace cv;
- using namespace std;
- #define TWO_PI 6.2831853071795864769252866
- double generateGaussianNoise()
- {
- static bool hasSpare = false;
- static double rand1, rand2;
- if(hasSpare)
- {
- hasSpare = false;
- return sqrt(rand1) * sin(rand2);
- }
- hasSpare = true;
- rand1 = rand() / ((double) RAND_MAX);
- if(rand1 < 1e-100) rand1 = 1e-100;
- rand1 = -2 * log(rand1);
- rand2 = (rand() / ((double) RAND_MAX)) * TWO_PI;
- return sqrt(rand1) * cos(rand2);
- }
- void AddGaussianNoise(Mat& I)
- {
- // accept only char type matrices
- CV_Assert(I.depth() != sizeof(uchar));
- int channels = I.channels();
- int nRows = I.rows;
- int nCols = I.cols * channels;
- if(I.isContinuous()){
- nCols *= nRows;
- nRows = 1;
- }
- int i,j;
- uchar* p;
- for(i = 0; i < nRows; ++i){
- p = I.ptr<uchar>(i);
- for(j = 0; j < nCols; ++j){
- double val = p[j] + generateGaussianNoise() * 128;
- if(val < 0)
- val = 0;
- if(val > 255)
- val = 255;
- p[j] = (uchar)val;
- }
- }
- }
- int main( int argc, char** argv )
- {
- if( argc != 2)
- {
- cout <<" Usage: display_image ImageToLoadAndDisplay" << endl;
- return -1;
- }
- Mat image;
- image = imread(argv[1], 1); // Read the file
- if(! image.data ) // Check for invalid input
- {
- cout << "Could not open or find the image" << std::endl ;
- return -1;
- }
- namedWindow( "Display window", WINDOW_AUTOSIZE ); // Create a window for display.
- imshow( "Display window", image ); // Show our image inside it.
- // Add Gaussian noise here
- AddGaussianNoise(image);
- namedWindow( "Noisy image", WINDOW_AUTOSIZE ); // Create a window for display.
- imshow( "Noisy image", image ); // Show our image inside it.
- waitKey(0); // Wait for a keystroke in the window
- return 0;
- }
添加了高斯噪音的lena图片:
参考:
1. http://mathworld.wolfram.com/Box-MullerTransformation.html
2. http://en.wikipedia.org/wiki/Box%E2%80%93Muller_transform
3. Sanka et al. Image processing, analysis and machine vision. 3rd edition.