Salut
je travail avec c++ Builder 6, et cherche un code pour bruiter une image bmp par un bruit gaussien, est ce que vous pouvez m'aider
Merci d'avance![]()
Salut
je travail avec c++ Builder 6, et cherche un code pour bruiter une image bmp par un bruit gaussien, est ce que vous pouvez m'aider
Merci d'avance![]()
Un thésard a souvent un problème de motivation jusqu'au moment où il aura un problème de temps....
L'image que tu lis finit dans un tableau dont le format est lié à celui de ton image (en noir et blanc, tu n'auras qu'une composante, en RGB, trois).
Chaque composante varie de 0 à max (max = 255 dans la plupart des cas)
Il te faut un générateur de nombres aléatoires qui te produise des nombres aléatoires selon une loi gaussienne (je ne sais pas ce que produit le générateur par défaut).
Ensuite pour chaque pixel, il faut générer un bruit d'amplitude A (A = 20 par exemple). Tu auras dont un bruit B de allant de -20 à 20.
A chaque composante de chaque pixel, tu ajoutes ce bruit (en écrétant à [0..255]) et tu sauvegardes la nouvelle image ainsi obtenue.
Sinon il y a la solution d'utiliser la librairie CImg de l'Inria qui contient des fonctions déjà codées pour le traitement des images...
Salut kaji,
Merci pour ta réponse, tu ma donné une idée pour commencer, maintenant je trouve une difficulté pour la formule de la loi de gausse qui est f(x)=exp[-1/2((x-m)/écart type))²]/[écart type(sqrt(2pi)], j'aimerai bien que quelqu'un m'explique cette formule dans le cadre du géneration d'un bruit gaussien afin de bruiter une image.
merci d'avace![]()
Un thésard a souvent un problème de motivation jusqu'au moment où il aura un problème de temps....
Ta courbe f(x) est la fameuse "courbe en cloche" de Gauss, aussi appelée "Loi Normale". Tu peux la voir ici http://fr.wikipedia.org/wiki/Loi_normale
Déjà il faut savoir ce que te donne le générateur de nombres aléatoires de C++...
Je ne savais pas non plus et j'ai écrit un petit programme qui tire 100000 nombres de 0 à 100 et je compte le nombre dans le tableau tabNbSorties, le nombre de sorties. Par exemple, si le 50 et tiré une première fois, tabNbSorties[50] vaut 1. Si il sort une seconde fois, tabNbSorties[50] vaudra 2, etc.
A la fin j'enregistre tous les compteurs du tableau tabNbSorties dans un fichier texte au format lisible par Scilab (il est gratuit). Il suffit de copier-coller le texte "y = [4 5 6 ... 7 5 4]; bar(y);" dans Scilab et tu obtiens un magnifique histogramme !
Mon programme (C++ standard)
En sortie, j'obtiens le tableau suivant par exemple :
Code : 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 #include <stdlib.h> #include <iostream> #include <fstream> using namespace std; // // Renvoie un nombre aléatoire entre nMin et nMax // int getNbAleatoire(int nMin, int nMax) { return (int)(nMin + ((float) rand() / RAND_MAX * (nMax - nMin + 1))); }// getNbAleatoire int main(int argc, char *argv[]) { int nAmorce = 2;// amorce (vaut 1 par défaut) srand(nAmorce); const int ncMin = 0; const int ncMax = 99; const int ncTirages = 100000; // Raz du tableau de comptage int tabNbSorties[ ncMax + 1]; for (int nI = ncMin; nI <= ncMax; ++nI ) { tabNbSorties[ nI ] = 0; } // Tirages et enregistrements for (int nI = 1; nI <= ncTirages; ++ nI) { int nbAleat = getNbAleatoire( ncMin, ncMax ); tabNbSorties[ nbAleat ]++; } // Enregistrement de l'histogramme ofstream f_out; f_out.open("histo.txt", ios::out ); f_out << "y = ["; for (int nI = ncMin; nI <= ncMax; ++nI ) { f_out << tabNbSorties[ nI ] << " "; } f_out << "]; bar(y);"; f_out.close(); // fin system("PAUSE"); return EXIT_SUCCESS; }// main
Et là, on voit grâce à Scilab que l'histogramme est à peu-près plat.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 y = [1059 1037 976 937 1006 1023 990 983 1023 1034 1010 1008 982 1019 944 1011 1005 951 960 1050 1049 981 973 1024 1003 1008 976 917 1047 976 1014 1041 967 1011 943 928 1019 1050 1029 998 1009 975 960 1050 992 992 1044 1014 1000 1053 964 947 993 950 1055 1017 1000 1047 985 1018 1012 1028 1029 1018 973 1024 1012 1027 1009 1005 1026 991 968 966 960 987 938 935 963 1017 1058 1057 965 1007 1007 954 1021 1013 978 1039 1010 986 975 984 1000 999 996 1053 972 1009 ]; bar(y);
Et donc tu peux te servir du générateur de nombres aléatoires standard pour générer des valeurs de "x".
Préalablement, tu calcules un histogramme (un tableau, donc) y = f(x) qui suive ta loi nomale Par exemple de x = 0 à x = 20 avec un maxi en x = 10 (y = f(10) = 20 par exemple) (La "cloche est centrée en x = 10 avec un mini en x = 0 et x = 20).
Ensuite, pour chaque pixel, tu génères un nombre aléatoire x entre 0 et 20. Le bruit correspondant vaut B = y = f(x) et tu l'ajoutes aux composantes de ton pixel. Ecrétage éventuel à [0 .. 255], et le tour est joué.
Eventuellement, tu calcules B = y - 10 pour avoir un bruit de -10 à 10...
Salut kaji
Résumant se que j'ai compris:
- Je doit calculer un tableau histogramme selon la loi de gauss "cloche de gauss", donc j'aurai un tableau H allant du min jusqu'au max , je procède comme tu a fait dans ton code:
sauf pour la formule retournée j'utilise celle de gauss.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 Renvoie un nombre aléatoire entre nMin et nMax // int getNbAleatoire(int nMin, int nMax) { return (int)(nMin + ((float) rand() / RAND_MAX * (nMax - nMin + 1))); }// getNbAleatoire
- Pour chaque pixel Générer un nombre aléatoire x entre min et max par le générateur de builder; et trouver le bruit B correspondant dans le tableau H[x] tel que B=H[x]
- En fin ajouter ce bruit B aux composantes de chaque pixel.
Est ce que j'ai bien compris là?
Merci d'avance![]()
Un thésard a souvent un problème de motivation jusqu'au moment où il aura un problème de temps....
Bonjour,
si tu regardes parmi les plugins d'ImageJ, tu en trouveras un qui fait ce que tu demandes. Le code est disponible![]()
Consignes aux jeunes padawans : une image vaut 1000 mots !
- Dans ton message respecter tu dois : les règles de rédaction et du forum, prévisualiser, relire et corriger TOUTES les FAUTES (frappes, sms, d'aurteaugrafe, mettre les ACCENTS et les BALISES) => ECRIRE clairement et en Français tu DOIS.
- Le côté obscur je sens dans le MP => Tous tes MPs je détruirai et la réponse tu n'auras si en privé tu veux que je t'enseigne.(Lis donc ceci)
-ton poste tu dois marquer quand la bonne réponse tu as obtenu.
Salut ToTo13
Je voie que ImageJ concerne java; rappelant que je travaille avec c++ builder, ainsi que ma question été sur l'algorithme à suivre pour faire l'ajout d'un bruit gaussien à une image
Dans les discussions précédentes, kaji ma proposé une solution
j'ai résumé après ce que j'ai retenu..Déjà il faut savoir ce que te donne le générateur de nombres aléatoires de C++...
Je ne savais pas non plus et j'ai écrit un petit programme qui tire 100000 nombres de 0 à 100 et je compte le nombre dans le tableau tabNbSorties, le nombre de sorties. Par exe........
Et j'ai demandé est ce q j'ai bien compris l'algorithme?Résumant se que j'ai compris:
* Je doit calculer un tableau histogramme selon la loi de gauss "cloche de gauss", donc j'aurai un tableau H allant du min jusqu'au max , je pr..........
j'ai cherché sur le forum et j'ai pas trouvé, merci ToTo de me donné un lien précis ou de m'expliquer le procédé.
Merci d'avance![]()
Un thésard a souvent un problème de motivation jusqu'au moment où il aura un problème de temps....
Bonjour,
je sais lire merci... mais la partie d'ajout du bruit ressemble plus à du C que du Java.
Voilà ce que l'on trouve en cherchant "Gaussian" ou "Noise" dans la page.
Consignes aux jeunes padawans : une image vaut 1000 mots !
- Dans ton message respecter tu dois : les règles de rédaction et du forum, prévisualiser, relire et corriger TOUTES les FAUTES (frappes, sms, d'aurteaugrafe, mettre les ACCENTS et les BALISES) => ECRIRE clairement et en Français tu DOIS.
- Le côté obscur je sens dans le MP => Tous tes MPs je détruirai et la réponse tu n'auras si en privé tu veux que je t'enseigne.(Lis donc ceci)
-ton poste tu dois marquer quand la bonne réponse tu as obtenu.
Un thésard a souvent un problème de motivation jusqu'au moment où il aura un problème de temps....
Oui, c'est ça, tu remplis un tableau
Avec tabH[0], la première valeur de ta courbe en cloche, tabH[49], le maxi (20 par exemple) et tabH[99], la dernière valeur.
Code : Sélectionner tout - Visualiser dans une fenêtre à part float tabH[100];//par exemple
Pour chaque pixel, tu tires un nombre aléatoire x dans l'intervalle [0, 99] (la taille de ton histogramme) et le bruit gaussien aléatoire correspondant sera B = tabH[x].
Exactement. A chaque pixel, tu tires un "x" et tu calcules le bruit correspondant par B = tabH[x] que tu ajoutes à chaque composante du pixel (en écrêtant à la bonne plage souvent [0 .. 255])
Enfin, il y a tout de même largement mieux pour générer un nombre aléatoire selon une gaussienne ! cf mon tutoriel, et si tu dois vraiment le réaliser par toi-même cherche du côté de la transformation de Box-Muller !
Lequel ? Je ne l'ai pas trouvé dans tes pages... Il faut utiliser la librairie Boost ?
Sur Wikipédia, par exemple ?
D'après ce que j'ai compris, avec cette méthode, les nombres aléatoires "selon un gaussienne" se calculent par paire (z0 et z1) à partir de deux nombres aléatoires "linéaires" (x et y)
Algo simplifié :
- tirer x et y
- calculer s = x^2 + y^2
- z0 = x . sqr{-2.log(s)/s};//(forme cartésienne)
- z1 = y . sqr{-2.log(s)/s}
Pour chaque nombre aléatoire, il faut calculer des carrés, des racines carrées, des logarithmes, des multiplications... Et dans la forme polaire, c'est plus compliqué, il y a des calculs de cosinus !!
Il me semble que cette méthode n'est intéressante que pour la résolution des équations différentielles...
Dans notre cas, je ne vois vraiment pas l'intérêt... (à part pour perdre du temps et faire un code compliqué...)
1) oui, celui dont j'ai donné le lien plus haut, et oui, ça utilise Boost.
2) Tu peux t'amuser avec un histogramme cumulé, mais tu dois le parcourir et si tu veux un peu de précision, Box-Muller sera largement plus avantageux.
Oui, ça-y-est, j'ai trouvé, il faut aller dans http://matthieu-brucher.developpez.c.../boost/random/, puis "Distributions" dans "Autres distributions", choisir : normal_distribution.
Et il les calcule comment ses nombres aléatoires à distribution Gaussienne, Boost ? Si ça se trouve, il fait ce que je propose...
Je propose un histogramme non cumulé et simplement un accès direct au nième élément... Plus simple, tu meurs !
C'est vrai que la méthode Box-Muller est plus précise et moins consommatrice en mémoire (pour plus de précision avec ma méthode, prendre un histogramme plus grand, ou faire une interpolation entre tabH[i] et tabH[i+1] [ça coûte 2 multiplications, une somme et une division]).
Ceci dit, pour ajouter du bruit aux pixels d'une image il faut nécessairement des entiers... et donc un résultat discrétisé moins précis d'un résultat continu... La précision n'est donc pas ici un argument prépondérant.
De plus avec Box-Muller, il faut calculer des carrés, des racines carrées, des logarithmes, des multiplications à chacun des nombreux pixels d'une image... j'ai peur que ce soit beaucoup plus lent.
Mais en tous cas, je ne connaissais pas Box-Muller, ça peut servir, merci.![]()
Une transformation Box-Muller, on se demande pourquoi
Un histogramme non cumulé ne te servira à rien, il te faut un histogramme cumulé pour générer tes nombres. A moins que je n'ai pas compris ta méthode, il n'y a aucune chance pour que ton code fasse ce que tu crois (parole de statisticien).
J'ai relu ce que tu penses à faire, je te rassure tout de suite, ça ne fait pas du tout une courbe gaussienne(ou plus précisément, ça ressemble à une gaussienne dans le bouillard)
Si tu veux générer une loi aléatoire à partir d'une loi uniforme, tu DOIS partir de p(x<X) et non d(x=X). Une fois que tu as ce tableau, tu peux générer un nombre aléatoire entre 0 et 1 et prendre l'indice correspondant à cette valeur dans ton tableau cumulé. A partir de cet indice, tu as ton nombre aléatoire selon une transformation linéaire. C'est la SEULE solution pour générer n'importe quelle loi de manière acceptable (trace donc l'histogramme final d'une génération avec ton algorithme). De cette manière, tu répartis de manière uniforme (et correctement) les échantillons.
Dans ton exemple, au milieu du tableau, tu génères le nombre 20 le plus grand nombre de fois. Un bruit dans une image, c'est de moyenne nulle.
Plus sérieusement, pour calculer les indices dans ton tableau, je te souhaite bon courage (pour calculer l'intégrale par morceau de la loi gaussienne).
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager