Utile pour générer du bruit sur des images :
Le code est inspiré de l'API Java (classe Random)
Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47 /** * Défini un classe permettant de générer des nombres suivant une loi * normale. * * Cette classe utilise la technique de box-muller pour générer les valeurs * * Cette classe n'est pas multithread-safe * * @version 1.0 */ class GaussianRandomizer : public FRandomizer { protected: float _sigma; /** * Indique le nombre suivant dans le cas ou _haveNextGaussian est vrai */ float _nextGaussian; /** * indique si _nextGaussian est valide */ bool _haveNextGaussian; float _mean; public: /** * Défini un générateur suivant une loi gaussienne * * @param sigma la variance de la loi * @param mean l'espérance de la loi * * @throw Millie::IllegalArgument si @a sigma<0 */ GaussianRandomizer(float sigma, float mean =0.0f); /** * @return un réel selon la loi de distribution gaussienne * * @warning Cette méthode n'est pas Multithread Safe */ float get(void); };
Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47 #include "GaussianRandomizer.hpp" #include <ctime> #include <cstdlib> #include <cmath> using namespace Millie; GaussianRandomizer::GaussianRandomizer(float sigma, float mean) { if(sigma<0) throw Millie::IllegalArgument("GaussianRandomizer"); _sigma = sigma; _mean = mean; _haveNextGaussian = false; _nextGaussian = 0.0f; } float GaussianRandomizer::get() { /* * Le code est inspiré du code source Java de la classe Random */ if (_haveNextGaussian) { _haveNextGaussian = false; return _nextGaussian; } else { float v1, v2, s; do { v1 = 2 * (rand()/(RAND_MAX+1.0f)) - 1; /*entre -1 et 1*/ v2 = 2 * (rand()/(RAND_MAX+1.0f)) - 1; /*entre -1 et 1*/ s = v1 * v1 + v2 * v2; } while (s >= 1 || s == 0); float multiplier = sqrt(-2 * log(s)/s); _nextGaussian = v2 * multiplier * _sigma + _mean; _haveNextGaussian = true; return v1 * multiplier * _sigma + _mean; } }
EDIT : En java, il ne faut pas se prendre la tête, il y a Random#nextGaussian() * sigma + mean
PRomu@ld : sources
Partager