给图像添加高斯噪音

通过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 
#include 
#include 

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(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张图片

参考:

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.



你可能感兴趣的:(图像处理)