目录
note
Box-Muller算法
// U1服从均匀分布,U2服从均匀分布
// X = sqrt(-2*ln(U1)) * sin(2 * PI * U2)服从标准正态分布
// Y = sqrt(-2*ln(U1)) * cos(2 * PI * U2)服从标准正态分布
code
void UniformN(float* p, int cnt) {
int x = 0;
srand(time(nullptr));
for (int i = 0; i < cnt; ++i) {
x++; // 意义:单纯占用时间
int r = rand();
r = r % 1000;
float rate = (float)r / 1000.0;
p[i] = (rate);
}
}
void GaussRandomN(float mean, float stdDev, float& randomN) {
float r[2]; // 两个均匀分布随机变量
UniformN(r, 2);
float a = sqrtf(-2*log(r[0]));
float b = 2*PI*r[1];
float c = a*cosf(b); // 标准正态分布变量
randomN = mean + c * stdDev;
}
void GaussNoise(int cnt, int xMax, int yMax, int channels, Scalar& mean, Scalar& stdDev, Mat& res) {
if (channels == 1) {
res = Mat(yMax, xMax, CV_8UC1, Scalar(0));
}
else if (channels == 3) {
res = Mat(yMax, xMax, CV_8UC3, Scalar(0));
}
else {
return;
}
RNG rngOBJ(time(nullptr)); // 产生随机坐标的随机分配器
for (int i = 0; i < cnt; ++i) {
int x = rngOBJ.uniform(0, xMax);
int y = rngOBJ.uniform(0, yMax);
if (channels == 1) {
float noise;
GaussRandomN(mean[0], stdDev[0], noise);
res.at<uchar>(x,y) = (uchar)noise;
}
else if (channels == 3) {
float noiseB, noiseG, noiseR;
GaussRandomN(mean[0], stdDev[0], noiseB);
GaussRandomN(mean[1], stdDev[1], noiseG);
GaussRandomN(mean[2], stdDev[2], noiseR);
res.at<Vec3b>(x,y) = Vec3b((uchar)noiseB,(uchar)noiseG,(uchar)noiseR);
}
}
}
test