给图像添加高斯噪音

通过Box-Muller变换可以产生Gaussian噪音

 

Box-Muller变换:假设随机变量x1, x2来自独立的处于[0,1]之间的均匀分布,则经过下面两个式子产生的随机变量z1, z2服从标准高斯分布:



实现代码(引自维基百科)

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #define TWO_PI 6.2831853071795864769252866  
  2.    
  3. double generateGaussianNoise()  
  4. {  
  5.     static bool hasSpare = false;  
  6.     static double rand1, rand2;  
  7.    
  8.     if(hasSpare)  
  9.     {  
  10.         hasSpare = false;  
  11.         return sqrt(rand1) * sin(rand2);  
  12.     }  
  13.    
  14.     hasSpare = true;  
  15.    
  16.     rand1 = rand() / ((double) RAND_MAX);  
  17.     if(rand1 < 1e-100) rand1 = 1e-100;  
  18.     rand1 = -2 * log(rand1);  
  19.     rand2 = (rand() / ((double) RAND_MAX)) * TWO_PI;  
  20.    
  21.     return sqrt(rand1) * cos(rand2);  
  22. }  

给图片添加高斯噪音的代码:

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #include <opencv2/core/core.hpp>  
  2. #include <opencv2/highgui/highgui.hpp>  
  3. #include <iostream>  
  4.   
  5. using namespace cv;  
  6. using namespace std;  
  7.   
  8. #define TWO_PI 6.2831853071795864769252866  
  9.    
  10. double generateGaussianNoise()  
  11. {  
  12.     static bool hasSpare = false;  
  13.     static double rand1, rand2;  
  14.    
  15.     if(hasSpare)  
  16.     {  
  17.         hasSpare = false;  
  18.         return sqrt(rand1) * sin(rand2);  
  19.     }  
  20.    
  21.     hasSpare = true;  
  22.    
  23.     rand1 = rand() / ((double) RAND_MAX);  
  24.     if(rand1 < 1e-100) rand1 = 1e-100;  
  25.     rand1 = -2 * log(rand1);  
  26.     rand2 = (rand() / ((double) RAND_MAX)) * TWO_PI;  
  27.    
  28.     return sqrt(rand1) * cos(rand2);  
  29. }  
  30.   
  31.   
  32. void AddGaussianNoise(Mat& I)  
  33. {  
  34.     // accept only char type matrices  
  35.     CV_Assert(I.depth() != sizeof(uchar));  
  36.   
  37.     int channels = I.channels();  
  38.   
  39.     int nRows = I.rows;  
  40.     int nCols = I.cols * channels;  
  41.   
  42.     if(I.isContinuous()){  
  43.         nCols *= nRows;  
  44.         nRows = 1;  
  45.     }  
  46.   
  47.     int i,j;  
  48.     uchar* p;  
  49.     for(i = 0; i < nRows; ++i){  
  50.         p = I.ptr<uchar>(i);  
  51.         for(j = 0; j < nCols; ++j){  
  52.             double val = p[j] + generateGaussianNoise() * 128;  
  53.             if(val < 0)  
  54.                 val = 0;  
  55.             if(val > 255)  
  56.                 val = 255;  
  57.   
  58.             p[j] = (uchar)val;  
  59.   
  60.         }  
  61.     }  
  62.   
  63. }  
  64.   
  65.   
  66.   
  67. int main( int argc, char** argv )  
  68. {  
  69.     if( argc != 2)  
  70.     {  
  71.      cout <<" Usage: display_image ImageToLoadAndDisplay" << endl;  
  72.      return -1;  
  73.     }  
  74.   
  75.     Mat image;  
  76.     image = imread(argv[1], 1); // Read the file  
  77.   
  78.     if(! image.data ) // Check for invalid input  
  79.     {  
  80.         cout << "Could not open or find the image" << std::endl ;  
  81.         return -1;  
  82.     }  
  83.   
  84.     namedWindow( "Display window", WINDOW_AUTOSIZE ); // Create a window for display.  
  85.     imshow( "Display window", image ); // Show our image inside it.  
  86.   
  87.     // Add Gaussian noise here  
  88.     AddGaussianNoise(image);  
  89.   
  90.     namedWindow( "Noisy image", WINDOW_AUTOSIZE ); // Create a window for display.  
  91.     imshow( "Noisy image", image ); // Show our image inside it.  
  92.     waitKey(0); // Wait for a keystroke in the window  
  93.   
  94.   
  95.     return 0;  
  96. }  

添加了高斯噪音的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.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值