# Gnral Dveloppement > Algorithme & Mathmatiques > Traitement d'images >  Image et Variance

## mmx

Bonjour,


J'ai beaucoup cherch (peut tre pas au bon endroit) et j'ai trouv un grand nombre d'explication concernant la variance mais trs peu de chose sur la variance applique  une image.

J'aimerais coder moi-mme ma mthode de calcul de la variance d'une image. Je connais la thorie et la formule mathmatique de la variance, ce qui me pose problme, c'est la manire de l'appliquer  une image.

Si on considre une image RGB. Dois-je choisir un lment structurant ? Dois-je calculer la variance de l'lment structurant pour R, puis sparment pour G, et enfin pour B ou est-ce que c'est un calcul global ?

J'ai beaucoup de question surtout parce que j'ai aucune ide sur le droulement de ce calcul, une fois claircit, certaines questions trouverons une rponse d'elles-mme  ::): 

Merci d'avance.

----------


## DocteurV

Bonjour mmx,

La variance d'une image est la variance des intensits des pixels, au sens statistique. C'est  dire la moyenne des carrs des carts  la moyenne des intensits.

Pour une image RGB, tu as deux solutions :
- Calculer la variance de chaque plan et combiner les rsultats (moyenne, mdiane ...)
- Combiner les 3 plans et calculer la variance du plan ainsi obtenu

Tu n'as pas besoin d'lment structurant pour calculer la variance globale d'une image. 

Etapes pour coder le calcul de la variance d'une image d'intensits :
Double boucle sur tes lignes et colonnes pour calculer la somme de tous tes pixelsEn divisant par le nombre de pixels tu obtiens la moyenne de ton imageDouble boucle sur tes lignes et colonnes pour calculer la somme des carrs des carts  la moyenne : (intensit - moyenne).En divisant par le nombre de pixels tu obtiens la variance de ton image

----------


## pseudocode

C'est plus simple d'utiliser la formule "var(x)= E(x)-E(x)".

C'est  dire calculer la somme des (valeurs^2) et la somme des (valeurs) sur la zone considre. Puis d'en faire la moyenne en divisant pas le nombre de pixels de la zone. Puis enfin la diffrence pour avoir la variance.

Ca vite de faire 2 fois le parcours. De plus, ca permet d'utiliser les "images sommes" pour calculer rapidement la variance locale sur des zones rectangulaires.

----------


## mmx

Hello,

Merci pour vos rponses rapides. En effet, j'avais trouv que Zavonen expliquait a bien aussi dans le ce fil (http://www.developpez.net/forums/d58...lcul-variance/).

Je suis tomb sur a aussi : Lien, mais il applique un seuillage, ce qui binarise l'image  la fin.




> - Calculer la variance de chaque plan et combiner les rsultats (moyenne, mdiane ...)
> - Combiner les 3 plans et calculer la variance du plan ainsi obtenu


Donc soit je me cogne 3 fois le calcule de la variance, soit je dduis d'abord un niveau de gris et je calcule la variance qu'une seule fois.

Il y a un truc que je ne saisis toujours pas. En sortie de ce calcule de variance, je veux une image, donc c'est forcment quelque chose de local qu'il faut que je fasse non ? d'o le choix d'un lment structurant, j'insiste mais sinon je suis vraiment  ct de la plaque  ::): 

Et si j'applique le filtre "Variance" de imageJ  une image en couleur, a renvoie une autre image, mais pas en niveau de gris, il y a encore des couleurs...

C'est parce que c'est vendredi, ou c'est que j'ai simplement du mal ?  ::lol::

----------


## DocteurV

> En sortie de ce calcule de variance, je veux une image,


Aaah mais a change tout!!
Tu ne cherches donc pas la variance de ton image, mais l'image des variances locales !

Dans ce cas il faut, pour chaque pixel de chaque plan, calculer la variance de son voisinage local : Classiquement, une fentre NxN centre sur le pixel. Ensuite tu affectes la valeur de variance au pixel correspondant dans l'image rsultat.

Ainsi, effectivement, tu obtiendras une image sur 3 canaux avec une valeur de variance locale en chaque pixel.

----------


## mmx

Re,


bon, il me semblait bien qu'il fallait faire a localement. Dsol de ne pas avoir tait assez clair.

Petit exemple : je prends une fentre 3x3 du plan R, j'ai donc la distribution suivante compose de 8 valeurs (le neuvime tant le pixel central) :
250; 250; 107; 81; 125; 40; 128; 49;

A : La somme : 250 + 250 + 107 + 81 + 125 + 40 + 128 + 49  = 1030
B : La somme des carr : 179 020

variance = B/n - (A/n)^2 = 179020/8 - (1030/8)^2 = (environ) 5800

Hum, y a un souci nop ? j'ai besoin d'une valeur locale entre 0-255 pour affecter la valeur au pixel central de la fentre. J'ai oubli une retenue quelque part ? :p

----------


## pseudocode

> Hum, y a un souci nop ? j'ai besoin d'une valeur locale entre 0-255 pour affecter la valeur au pixel central de la fentre. J'ai oubli une retenue quelque part ? :p


Dans le traitement d'image (et du signal) on manipule gnralement des intensits ayant des valeurs relles entre 0 et 1. 

Donc il faut convertir les valeurs entires 0-255 en valeurs relles 0...1, faire les calculs, et repasser en valeur entire 0-255. 

Bien sur, on peut souvent optimiser les calculs pour tout faire en entier 0-255 mais il ne faut pas se planter dans les facteurs de normalisation

----------


## mmx

Bonjour, Bonsoir,

j'ai implment le filtre afin de calculer les variances locales de mon image. Je rcupre la somme des pixel sur chaque plan spars (R, G, B) et la somme des carrs de la mme manire. J'ai une fentre "se" de 3x3 contenant des 1 partout.

je parcours mon image sur x, puis y puis sur les lignes et colonnes de "se".


```

```

La variable size reprsente la taille d'une dimension de "se" : donc nombre de pixel dans la fentre = size * size. (car, pour l'instant, tout les lments de "se" sont  1 et "se" est carr).



```

```



```

```

Auriez-vous une ide du pourquoi je n'obtiens pas ce que je devrais :
Ce que je veux obtenir :


Ce que j'obtiens : (c'est trs sombre  cause de la division par (255 * 255)


Ce que j'obtiens sans division par (255*255) :


J'ai comme qui dirait un petit problme  ::): 

Merci d'tre arriv jusque l.

----------


## pseudocode

```
byte red = (byte)((summSquareR / (size * size) - (summR / (size * size) * (summR / (size * size)))) * 255.0f);
```

Il faudrait voir le code complet mais ce parenthesage m'a l'air faux. Je te propose de crer des variables intermdiaires :

float area = size*size;
float meanR = summR/area;
float meanSquareR = summSquareR/area;
byte varR = (byte)(255f*( meanSquareR - meanR*meanR ));


Pour le calcul du rsultat final, je te conseille aussi de prendre l'cart type plutot que la variance, et de faire une moyenne pondre des 3 canaux (formule de luminosit)

float varRGB = 0.299f*varR + 0.587f*varG + 0.114f*varB;
float stddevRGB =  Math.sqrt(varRGB);

----------

