I.To generate Gaussian noise
Box-Muller:if random variable x and y are respectively independent generated from a uniform distribution with [0,1].we can use the formula below to produce a variable with Gaussian distribution.
z=sqrt(-2*lny)*cos(2*pi*x)
function:
double generateGaussianNoise(double mu, double sigma)
{
const double epsilon = std::numeric_limits<double>::min();
const double two_pi = 2.0*3.14159265358979323846;
static double z0, z1;
static bool generate;
generate = !generate;
if (!generate)
return z1 * sigma + mu;
double u1, u2;
do
{
u1 = rand() * (1.0 / RAND_MAX);
u2 = rand() * (1.0 / RAND_MAX);
} while (u1 <= epsilon);
z0 = sqrt(-2.0 * log(u1)) * cos(two_pi * u2);
z1 = sqrt(-2.0 * log(u1)) * sin(two_pi * u2);
return z0 * sigma + mu;
}
II.Add Gaussian noise to a picture
Mat AddGaussianNoise(const Mat& I, double mu, double sigma)
{
// 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;
}
Mat result = I.clone();
int i, j;
const uchar* p;
uchar* rp;
for (i = 0; i < nRows; ++i) {
p = I.ptr<uchar>(i);
rp = result.ptr<uchar>(i);
for (j = 0; j < nCols; ++j) {
double val = p[j] + generateGaussianNoise(mu, sigma);
if (val < 0)
val = 0;
if (val > 255)
val = 255;
rp[j] = (uchar)val;
}
}
return result;
}