I. l'Image en mémoire d'ordinateur : N&B, et couleur RVB▲
L'image est un tableau bidimensionnel de pixels(1). Pour une image en noir et blanc, chaque pixel est codé par un octet non signé. L'étendue des valeurs prises par un octet non signé est comprise entre 0 : codant la couleur noire, à 255 : codant la couleur blanche, en passant par tous les niveaux de gris du plus sombre (i.e. noir) au plus clair (i.e. blanc).
Le « Balayage Vidéo », expression datant des tubes cathodiques(2) consiste à parcourir une image ligne à ligne, de haut en bas, et pour chaque ligne, colonne par colonne de gauche à droite. Le signal vidéo, « analogique », codait à l'aide d'une tension le niveau de gris ou la luminance des pixels selon cet ordre. C'est ce signal qui était amplifié pour s'étendre sur la plage 0-5V, puis échantillonné dans le temps (en pixels), et discrétisé en 256 valeurs (de 0 à 255) pour donner une image numérique.
Le stockage en mémoire mono dimensionnelle d'un ordinateur n'a pas changé avec le développement des appareils photo et caméras numériques. Ainsi, les pixels sont codés sur un octet (8 bits) non signé (type unsigned char en Langage C). L'ordre du stockage est celui du Balayage Vidéo visualisé figure n°1.
Pour entrer dans le détail de ce stockage, soit Add = Add(0,0), l'adresse en mémoire du premier pixel de l'image (soit le pixel en haut et à gauche). Pour calculer l'adresse du pixel courant P(x,y), pour une image de nlig lignes et ncol colonnes (respectivement numérotées de 0 à nlig - 1 et de 0 à ncol - 1), il faut ajouter à Add la valeur du déplacement soit :
d = y * ncol + x.
D'où l'adresse du pixel courant Add (x,y) mentionnée figure n° 1.
Nous l'utiliserons dans la macro (terminologie du langage C) PIXEL(image,point) de l'environnement logiciel. Cette macro permet la lecture ou l'écriture de la valeur du pixel point dans l'image image.
En imagerie couleur RVB, le principe est le même qu'en N&B, sauf que trois octets non signés sont stockés par pixel (cf. figure n° 2). Ils correspondent respectivement aux canaux rouge, vert et bleu. Lorsqu'un objet est clair sur l'image d'un canal, il contient la couleur du canal dans l'image couleur. Par exemple pour la balise « Bleu - Rose » de la figure n° 3, le « bleu » du haut de la balise est en réalité un bleu cyan, contenant également du vert. Le rose du bas de la balise contient du rouge et du bleu.
Pour une image couleur le déplacement est : d = 3 * (y * ncol + x) . Il est multiplié par 3 par rapport à une image en N&B. À l'adresse du pixel est stockée la valeur de l'information « Rouge » du pixel : Add_R(x,y). L'information « Vert » est stockée à l'adresse suivante, puis l'information « Bleu ». Les formules sont présentées figure n° 2.
Le format YUV (cf. Figure n° 3), évoqué au chapitre précédent, est un autre format couleur. L'image est codée de manière différente : compatible avec le système PAL. Y est l'image des luminances (i.e. image N&B), U est l'image de la différence des rouges, et V de la différence des bleus. Ainsi, le rose du bas de la balise ressort dans les bandes U et V, car il contient du rouge et du bleu, tandis que le bleu du haut de la balise ne ressort que dans la bande V.
Ce format permet de séparer la Luminance des composantes de Chrominance(3). L'œil étant moins sensible à la chrominance qu'à la luminance, il est possible de comprimer les canaux de chrominance : une colonne sur deux pour le codage YUV 4:2:2 et une colonne sur quatre pour le codage YUV 4:1:1, sans pour autant trop dégrader notre perception. Nous reviendrons sur ces formats dans une série d'articles suivante.
II. Les formats simples : PGM et PPM ▲
Les formats PGM (fichiers d'extension .pgm) pour une image N&B et PPM (d'extension .ppm) pour une image couleur, sont très simples. Ils sont constitués d'un entête, suivi des valeurs des pixels de l'image, stockées octet par octet, sans compression, selon le balayage vidéo, comme précédemment décrit.
Les entêtes des formats .pgm et .ppm sont très ressemblants. Ils sont composés de trois lignes :
- deux octets constituant le Magic Number, c'est-à-dire permettant l'identification du format : P5 pour le format PGM codé binaire et P6 pour le PPM pour ce même codage ;
- ncol codé en ASCII, suivi d'un espace, puis de nlig également en ASCII, où ncol est le nombre de colonnes de l'image, et nlig le nombre de lignes ;
- le nombre de niveaux de gris possibles (4).
Des lignes de commentaires optionnelles, commençant par le caractère « # » peuvent apparaître dans l'entête, intercalées entre les lignes précédentes.
L'entête est suivi des données, à la ligne suivante, constituant une seule ligne. Ces données comportent 1 octet par pixel, pour une image en N&B au format PGM, 3 octets par pixel, dans l'ordre R, V et B pour une image couleur PPM.
Ainsi, l'entête d'une image au format 1/4 VGA, de résolution 320 x 240 est la suivante :
P5
# image personnelle PB
320 240
255
L'entête d'une image couleur au format .ppm est similaire, au « magic number » (i.e. première ligne) près :
P6
# image personnelle PB
320 240
255
Le format Bitmap de Windows, d'extension « .bmp » possède un entête plus complexe, où les informations sont redondantes. Par rapport au format « .ppm », notons deux différences fondamentales :
- le point origine de l'image est en bas et à gauche (au lieu d'être en haut et à gauche). L'axe Oy est donc dirigé vers le haut (au lieu d'être vers le bas). L'image est donc stockée en mémoire de manière renversée, par rapport au format PPM ;
- l'ordre des informations couleurs pour un pixel est B, V puis R (au lieu de R,V et B). Les couleurs ont subi une inversion par rapport au PPM.
La transformation permettant de réorganiser les données du format « .ppm » au format « .bmp » consiste à :
- recopier l'image ligne à ligne, dans l'ordre inverse de lignes ;
- recopier les informations de couleur pixel par pixel en intervertissant les composantes R et B.
Cette même transformation permet également de réorganiser les données dans le sens inverse : du format « .bmp » au format « .ppm ».
III. L'architecture d'un opérateur :▲
On appelle « Opérateur » de Traitement d'Image ou de Vision tout traitement appliqué à une image unique, ou à une image extraite d'une séquence. Tous les opérateurs possèdent des caractéristiques communes : nous allons les développer ci-dessous.
III-A. Le schéma d'un opérateur :▲
Prenons le cas d'un opérateur simple qui admet en entrée une image, dont le résultat est également une image. Un certain nombre d'opérateurs développés dans la suite de cet ouvrage rentrent dans cette catégorie.
L'opérateur sera lancé :
- d'un « shell » : fenêtre de commandes sous Linux,
- d'une fenêtre DOS (cmd) : équivalent d'un shell Linux, ou du menu « Démarrer » sous Windows,
à l'aide d'une commande comportant le nom de l'opérateur, ainsi que les noms des images source (i.e. sur laquelle l'opérateur est appliqué) et résultat. L'image source est stockée sous la forme d'un fichier sur le disque dur. Elle existe avant l'exécution de l'opérateur. L'image résultat est stockée sous la même forme, mais est créée lors de l'exécution de l'opérateur. Un opérateur plus complexe peut nécessiter plusieurs images sources et résultats, des paramètres de contrôle, ainsi que des fichiers autres que des images en lecture ou en écriture.
Un traitement informatique agit sur des données stockées en mémoire vive. Ainsi, les pixels de l'image sont recopiés, du fichier sur disque dur, en mémoire vive au début de l'exécution. L'image est traitée, puis les pixels de l'image résultat, en mémoire vive, sont ensuite recopiés dans un fichier sur disque dur, à la fin du traitement. Il ne faut pas oublier d'écrire au préalable l'entête de l'image dans le fichier image résultat.
L'opérateur (cf. figure n° 4) comporte deux parties :
- l'interface avec l'utilisateur, commune à tous les opérateurs de même type (par exemple admettant une image en entrée et une image en sortie) ;
- le traitement, ou l'opérateur proprement dit.
L'interface avec l'utilisateur consiste en :
- la récupération des noms des images, des paramètres, à partir de la ligne de commande(5) ;
- l'ouverture des fichiers images : en lecture pour l'(es) image(s) source(s), en écriture pour l'(es) image(s) résultat(s) ;
- la lecture de l'entête de l'image source ;
- la création des structures de données ;
- la lecture, à partir du(es) fichier(s) image(s) des pixels de l' (des) image(s) source(s) ;
- l'appel du traitement (ou opérateur par abus de langage) ;
- l'écriture dans le(s) fichier(s) image(s) résultat(s) de l'entête de(s) l'image(s),
- l'enregistrement des pixels de(s) l'image(s) résultat(s) dans le(s) fichier(s) image(s) ;
- la libération de la mémoire, et la fermeture des fichiers(6).
Toutes ces fonctionnalités font partie de l'environnement Logiciel de Traitement d'Image EdEnviTi, fourni sur le site www.developpez.com.
III-B. Balayage vidéo simple▲
III-B-1. Traitements simples▲
Le « Traitement » proprement dit, appelé également « Opérateur » comporte deux parties :
- le balayage des données : les pixels sont examinés les uns après les autres, selon un certain ordre. Pour plus de simplicité, mais également d'efficacité, nous choisissons le balayage vidéo(7) ;
- le traitement du pixel courant, c'est-à-dire de la donnée.
Pour un opérateur simple, le traitement du pixel courant ne nécessite que la connaissance du pixel courant lui-même. Ainsi, le balayage vidéo simple suffit. Celui-ci consiste à parcourir l'image, pixel par pixel selon le balayage vidéo précédemment décrit, c'est-à-dire dans l'ordre où sont stockés les pixels de l'image. Nous verrons dans une série d'articles suivante, que ce balayage des données peut être réalisé selon une implantation temporellement optimisée, c'est-à-dire plus rapide.
Pour une image de résolution nlig lignes x ncol colonnes, le balayage s'effectue ligne à ligne de y = 0 à y = nlig - 1, et pour chaque colonne de x = 0 à x = ncol - 1.
III-B-2. Algorithme du balayage vidéo simple▲
L'algorithme du balayage vidéo simple de l'image est le suivant, il nécessite deux boucles POUR (8) imbriquées :
* Pour y = 0 à y = nlig - 1
* Pour x = 0 à x = ncol - 1
° I(x,y) = a /* Exemple d'Ecriture du pixel */
° a = I(x,y) /* Exemple de Lecture du pixel */
Remarquons l'indentation (i.e. le retrait des instructions) proposée pour le balayage vidéo. En algorithmie classique, la boucle POUR interne portant sur la variable x, serait indentée (donc en retrait), par rapport à la boucle POUR externe portant sur la variable y. Ici, nous considérons que la structure algorithmique n'est pas la boucle POUR, mais le balayage vidéo composé des deux boucles POUR, d'où la non-indentation de la boucle POUR interne.
III-C. Notion de voisinage▲
Pour la plupart des opérateurs, plus complexes, le traitement du pixel courant nécessite la connaissance de la valeur de l'intensité du pixel, mais également des pixels voisins. Nous nous limiterons dans cet ouvrage à la trame carrée, c'est-à-dire où les pixels sont alignés selon les deux directions x et y.
Deux types de liaisons entre les pixels, ou Connexité sont utilisées dans la littérature :
- la 4-Connexité, où seuls les quatre voisins cardinaux : nord, sud, est et ouest sont considérés ;
- la 8 - Connexité, où les huit voisins du voisinage 3 x 3 sont considérés.
La différence essentielle entre la 4 et la 8-connexité, est qu'en 4-connexité tous les voisins sont à même distance du pixel central, soit a (taille de la maille) (cf. figure n° 5), alors qu'en 8-connexité les voisins cardinaux sont à la distance a, et les voisins diagonaux à une distance b = a √2. Certains « puristes »(9) vont encore plus loin. Ils utilisent la trame hexagonale, où deux lignes successives sont décalées. Avec cette trame, les six voisins du pixel central sont à même distance.
Avec la 8-connexité, deux chemins, ou liste de pixels voisins ou connexes, peuvent se croiser, sans qu'il y ait d'intersection, c'est-à-dire de pixel commun. Ceci n'est pas le cas en 4-connexité, comme le montre la figure n° 6.
La connexité, qu'elle soit 4 ou 8, nous amène à la notion de Voisinage, c'est-à-dire aux pixels de l'image, voisins du pixel courant. La figure n° 5 nous présente le voisinage 3 x 3 centré, c'est-à-dire de dimension 3 colonnes x 3 lignes autour du pixel courant, en 4 et en 8 connexité. C'est ce voisinage, le plus simple, que nous utiliserons dans cette série d'articles(10). Dans la littérature, de nombreux voisinages sont utilisés : carrés centrés de taille 5 x 5, 7 x 7, 9 x 9, etc., mais également non centrés : 2 x 2, 4 x 4, etc., de forme rectangulaire, circulaire, elliptique et même quelconque.
III-D. Balayage vidéo avec examen du voisinage 3 x 3 centré▲
III-D-1. Problème des bords▲
Lors du traitement du pixel courant, l'opérateur va alors devoir parcourir les pixels de son voisinage. Mais il falloir faire attention avec les pixels appartenant aux premières et dernières lignes et colonnes de l'image. En effet, pour ces pixels, le voisinage n'est a priori pas dans l'image.
Le voisinage 3 x 3 centré s'étend sur trois lignes : la ligne précédente, la ligne courante (celle du pixel courant) et la ligne suivante. Ainsi un pixel de la première ligne aura la première ligne de son voisinage en dehors de l'image, avant le premier pixel (cf. figure n° 7). Il en sera de même pour un pixel de la dernière ligne de l'image, dont la dernière ligne de son voisinage sera également en dehors de l'image, mais après le dernier pixel. Dans ces deux cas, la tentative d'accès à un pixel en dehors de l'image, c'est-à-dire hors de la mémoire dynamiquement allouée aura l'effet catastrophique de planter le programme.
Pour les pixels de la première et de la dernière colonne, le problème est légèrement différent. En effet, compte tenu du rebouclage « torique » de l'image, induit par son stockage mono dimensionnel, ligne à ligne en mémoire :
- le voisin de la colonne précédente d'un pixel de la première colonne se retrouve en dernière colonne de la ligne précédente ;
- le voisin de la colonne suivante d'un pixel de la dernière colonne se retrouve en première colonne de la ligne suivante.
Il n'y a donc plus d'accès hors de l'image, mais le voisinage n'est pas correct.
Ainsi, l'opérateur n'effectuera pas le traitement des pixels
des premières et dernières lignes et colonnes.
L'image de résolution ncol colonnes x nlig lignes sera donc balayée :
- en Y : de 1 à nlig - 2 ;
- en X : de 1 à ncol - 2.
III-D-2. Coordonnées relatives du voisinage▲
Pour faciliter l'examen du voisinage 3 x 3 du pixel courant, un système d'axes (O,i,j), relatif à ce voisinage va lui être attaché (cf. figure n° 8), (i,j) Є [0,2]2. Le point courant a pour coordonnées réelles (x,y) dans l'image et relatives (1,1) dans le voisinage 3 x 3 centré. Le point voisin a pour coordonnées réelles (xv,yv) dans l'image et relatives (i,j) Є [0,2]2 dans le voisinage. Les relations entre (xv,yv), (x,y) et (i,j) sont :
° xv = x + i - 1
Vérifions ces formules. Pour le point courant :
° i = 1, soit xv = x
° j = 1, yv = y
et pour le point voisin en haut et à gauche, origine du voisinage :
° i = 0, soit xv = x - 1
° j = 0, yv = y - 1
III-D-3. Algorithme du balayage vidéo avec examen du voisinage▲
L'algorithme du balayage vidéo de l'image, avec examen du voisinage 3 x 3 centré, comporte donc quatre boucles POUR imbriquées :
-
deux réalisant le balayage vidéo de l'image, sauf les bords :
- y allant de 1 à nlig - 2,
- x allant de 1 à ncol - 2 ;
-
deux réalisant le balayage vidéo du voisinage :
- j allant de 0 à 2,
- i allant de 0 à 2.
L'algorithme est le suivant(11) :
* Pour y = 1 à y = nlig - 2
* Pour x = 1 à x = ncol - 2
° ...
° Pour j = 0 à j = 2
° Pour i = 0 à i = 2
> xv = x + i - 1
> yv = y + j - 1
> I(xv,yv) = a /* Exemple d'écriture du pixel voisin */
> a = I(xv,yv) /* Exemple de lecture du pixel voisin */
III-D-4. Décomposition du voisinage : passé, présent, futur▲
Certains algorithmes utilisent la notion de Présent, Passé et Futur du voisinage 3 x 3 centré (cf. figure n° 9). Cette notion est relative au balayage vidéo de l'image. Ainsi, lors du traitement du pixel courant :
- les trois pixels de la ligne précédente du voisinage, ainsi que le pixel de gauche ont déjà été traités : ils constituent le voisinage Passé ;
- les trois pixels de la ligne suivante du voisinage, ainsi que le pixel de droite n'ont pas été traités : ils constituent le voisinage Futur ;
- le pixel courant est en cours de traitement : c'est le Présent.
III-E. Structures des données▲
Pour cette série d'articles d'introduction, c'est-à-dire que les opérateurs étudiés sont de bas niveau, nous n'utiliserons que deux structures de données (cf. figure n° 10) : le Point, et l'Image.
D'autres structures de données sont liées aux primitives Points d'Intérêt, Contours (Contours, Lignes Polygonales, etc.), Composantes Connexes, Régions. Elles seront étudiées dans une série d'articles suivante.
La structure Point de type EdPOINT (cf. figure n° 10) comporte seulement deux champs ou attributs : les coordonnées du point selon les axes Ox et Oy soit : x et y.
La création et l'accès aux coordonnées x et y de l' EdPOINT sont réalisés à partir d'un pointeur point défini par la déclaration: EdPOINT *point;
et par des macros définitions(12) : crea_POINT(point), POINT_X(point) et POINT_Y(point).
La structure image, de type EdIMAGE est plus complexe. Elle contient (cf. figure n° 10) :
-
l'entête de l'image : comprenant :
- nlig : le nombre de lignes, accessible par la macro NLIG(image), où image est un pointeur sur la structure EdIMAGE,
- ncol : le nombre de colonnes, accessible par la macro NCOL(image),
- prof : la profondeur, ou le type de l'image, accessible par la macro PROF(image)
(= 1 pour une image N&B, = 3 pour une image couleur RVB) ;
- un pointeur sur les données, c'est-à-dire les pixels de l'image, mais contenu dans une union de pointeurs, comportant des pointeurs les types suivants : octet non signé, entier, réel.
En effet, comme plusieurs types d'images sont utilisés par les logiciels fournis dans cet ouvrage, les codages possibles sont les suivants :
- en octets : N&B, RVB, YUV (images source et/ou résultat pour la visualisation) ;
- en entiers : image des étiquettes pour le stockage de résultats de segmentation, ou image de différence pour l'extraction du mouvement à bas niveau par différence d'images, pixel à pixel ;
- en réel, de type float, pour les images de distance de la Kinnect par exemple.
En imagerie N&B, la macro PIXEL(image, point) où image est un pointeur sur une structure EdIMAGE et point un pointeur sur une structure EdPOINT permet d'accéder en lecture ou en écriture à la valeur du pixel de l'image image à la position contenue dans point. En imagerie RVB, les macros permettant d'accéder respectivement aux trois composantes, Rouge, Verte et Bleue du pixel de l'image couleur RVB sont : PIXEL_R(image, point), PIXEL_V(image, point), et PIXEL_B(image, point).
III-F. Code C▲
Nous reviendrons en détail, dans le sixième article de la série, sur l'intérêt de l'environnement logiciel de traitement d'images EdEnviTI, et notamment l'utilisation des macros définitions précédemment évoquées. En effet, comme nous allons le voir dans les exemples de code source en langage C fournis ci-dessous, l'intérêt essentiel de ces macros définitions est de permettre à des étudiants à niveau BAC + 2 et BAC + 3, non informaticiens de programmer des opérateurs de base de traitement d'image.
Nous remarquerons qu'à une ligne des algorithmes du balayage vidéo simple et du balayage vidéo avec examen du voisinage 3 x 3 centré correspond, à l'exception près des accolades ouvrantes et fermantes des blocs d'instructions, une ligne de langage C dans les exemples ci-dessous.
III-F-1. Code correspondant au balayage vidéo simple en imagerie N&B▲
Le code source ci-dessous est l'implantation en Langage C, du balayage vidéo simple, en imagerie N&B, dans l'environnement logiciel de traitement d'image, conçu en 1992 pour les besoins en enseignement évoqués ci-dessus, repris pour le projet de recherche CLEOPATRE, puis mis à jour et traduit en anglais pour le projet Européen EDUMEC, dont cette série d'articles reprend les travaux.
Notons que le balayage vidéo est implanté à l'aide de deux boucles for, la boucle externe portant sur les lignes, et interne sur les colonnes. La boucle interne étant la seule instruction de la boucle externe, elle n'est pas incluse dans un bloc d'instructions matérialisé par des accolades : {…}.
L'indentation des codes sources ci-dessous reproduit l'indentation des algorithmes correspondants. La structure algorithmique étant le balayage vidéo de l'image ou du voisinage du pixel, la boucle for interne, sur la variable POINT_X(point) n'est pas indentée par rapport à la boucle for externe sur la variable POINT_Y(point).
for(POINT_Y(point) = 0; POINT_Y(point) < NLIG(image); POINT_Y(point)++)
for(POINT_X(point) = 0; POINT_X(point) < NCOL(image); POINT_X(point)++)
{
...
... = PIXEL(image, point); // Lecture du Pixel : image source
...
PIXEL(imres, point) = ... ; // Ecriture du Pixel : image resultat
}
Attention à une difficulté portant sur la condition de rebouclage. La ligne suivante de l'algorithme, correspondant à la boucle externe sur les lignes :
* Pour y = 0 à y = nlig - 1
s'implante de la manière suivante, et il en est de même pour la boucle interne sur les colonnes.
for(POINT_Y(point) = 0; POINT_Y(point) < NLIG(image); POINT_Y(point)++)
On valide bien que la condition : POINT_Y(point) < NLIG(image); permet à la variable POINT_Y(point) d'aller jusqu'à NLIG(image) - 1.
III-F-2. Code correspondant au balayage vidéo avec examen du voisinage en imagerie N&B▲
Le code source ci-dessous est l'implantation en Langage C, du balayage vidéo avec examen du voisinage 3 x 3 centré, en imagerie N&B, dans l'environnement logiciel EdEnviTI. Notons qu'il est implanté à l'aide de quatre boucles for.
Les deux boucles externes portant sur les variables POINT_Y(point) et POINT_X(point) constituent le balayage vidéo de l'image, sauf les bords. Les deux boucles internes portant sur les variables j et i constituent le balayage vidéo du voisinage 3 x 3 centré. La boucle de variable j porte sur les lignes, celle de variable i sur les colonnes.
Les coordonnées du point voisin pointv sont calculées à partir des coordonnées du point courant point et des coordonnées relatives (i,j) du point dans le voisinage.
for(POINT_Y(point) = 1; POINT_Y(point) < NLIG(image) - 1;
POINT_Y(point)++)
for(POINT_X(point) = 1; POINT_X(point) < NCOL(image) - 1;
POINT_X(point)++)
{
...
/* --- Balayage Video du voisinage 3x3 --- */
for(j = 0; j < 3; j++)
for(i = 0; i < 3; i++)
{
/* calcul des coordonnees absolues du point voisin */
POINT_X(pointv) = POINT_X(point) + i - 1;
POINT_Y(pointv) = POINT_Y(point) + j - 1;
...
... = PIXEL(image, pointv); // Lecture du Pixel Voisin : image source
} /* --- fin du balayage du voisinage --- */
...
PIXEL(imres, point) = ... ;// Ecriture du Pixel Courant : image resultat
}
III-F-3. Code correspondant au balayage vidéo simple en imagerie couleur RVB▲
Le code source ci-dessous est l'implantation en Langage C, du balayage vidéo simple, en imagerie couleur RVB, dans l'environnement logiciel EdEnviTI. Notons que le parcours du pixel courant est identique au balayage en imagerie N&B. Seule différence : l'accès aux composantes rouge, verte et bleue du pixel courant :
for(POINT_Y(point) = 0; POINT_Y(point) < NLIG(image); POINT_Y(point)++)
for(POINT_X(point) = 0; POINT_X(point) < NCOL(image); POINT_X(point)++)
{
...
... = PIXEL_R(image, point); // Lecture du Pixel Rouge: image source
... = PIXEL_V(image, point); // Lecture du Pixel Vert: image source
... = PIXEL_B(image, point); // Lecture du Pixel Bleu: image source
PIXEL_R(imres, point) = ... ; // Ecriture du Pixel Rouge: image resultat
PIXEL_V(imres, point) = ... ; // Ecriture du Pixel Vert: image resultat
PIXEL_B(imres, point) = ... ; // Ecriture du Pixel Bleu: image resultat
}
III-F-4. Code correspondant au balayage vidéo avec examen du voisinage en imagerie couleur RVB▲
Le code source ci-dessous est l'implantation en Langage C, du balayage vidéo avec examen du voisinage 3 x3 centré, en imagerie couleur RVB, dans l'environnement logiciel EdEnviTI. Compte tenu de tout ce qui vient d'être vu, sa compréhension ne devrait pas poser de problème :
for(POINT_Y(point) = 1; POINT_Y(point) < NLIG(image) - 1;
POINT_Y(point)++)
for(POINT_X(point) = 1; POINT_X(point) < NCOL(image) - 1;
POINT_X(point)++)
{
...
/* --- Balayage Video du voisinage 3x3 --- */
for(j = 0; j < 3; j++)
for(i = 0; i < 3; i++)
{
/* calcul des coordonnees absolues du point voisin */
POINT_X(pointv) = POINT_X(point) + i - 1;
POINT_Y(pointv) = POINT_Y(point) + j - 1;
...
... = PIXEL_R(image, pointv); // Lecture du Pixel Rouge: image source
... = PIXEL_V(image, pointv); // Lecture du Pixel Vert: image source
... = PIXEL_B(image, pointv); // Lecture du Pixel Bleu: image source
} /* --- fin du balayage du voisinage --- */
...
PIXEL_R(imres, point) = ... ; // Ecriture du Pixel Rouge: image resultat
PIXEL_V(imres, point) = ... ; // Ecriture du Pixel Vert: image resultat
PIXEL_B(imres, point) = ... ; // Ecriture du Pixel Bleu: image resultat
}
Coder un opérateur revient à reprendre l'un des quatre exemples précédents et à l'adapter.
IV. Opérateurs de visualisation▲
Cette section est consacrée à la visualisation d'une image. Nous commencerons à comprendre à l'aide d'un outil précieux : l'histogramme, le manque de contrastes sur une image, puis comment la rehausser. Ensuite, nous visualiserons l'effet de la quantification, c'est-à-dire du nombre de bits de l'octet sur lequel sont codés les pixels de l'image. Enfin nous étudierons les algorithmes et visualiserons les effets des opérateurs portant sur la résolution de l'image : la réduction et le zoom.
IV-A. Histogramme▲
IV-A-1. Répartition des niveaux de gris▲
L'Histogramme est l'un des rares outils dont nous disposons pour interpréter le contenu photométrique (i.e. la répartition des niveaux de gris des pixels) de l'image. C'est un outil d'interprétation global, car même un histogramme local (i.e. dans le voisinage d'un point) doit comporter suffisamment de pixels. Son principal inconvénient est de ne pas tenir compte de la répartition spatiale des pixels, ce que l'on a généralement besoin pour une analyse plus fine, telle que pour l'analyse de texture(13). Mais nous n'aborderons pas cette notion dans cet ouvrage.
L'histogramme est un tableau mono dimensionnel de 256 valeurs, H(n) pour n є [0, 255], dont chacune est le nombre de fois où le niveau de gris n apparaît dans l'image. Il suffit donc d'effectuer un balayage vidéo de l'image, et de compter chaque valeur des pixels.
IV-A-2. Algorithme de calcul de l'histogramme▲
L'algorithme est le suivant :
* Histo[256] : tableau de 256 valeurs, initialisées à 0
* Pour y = 0 à y = Nlig - 1
* Pour x = 0 à x = Ncol - 1
° Histo[I(x,y)]++
IV-A-3. Utilisation d'un histogramme▲
Qu'apprenons-nous en regardant l'histogramme de l'image de Lenna (figure n° 11 : image (a), histogramme (b)). En regardant la partie gauche de l'histogramme : n proche de 0, il n'y a pas ou peu de pixels noirs (0 à 10 par exemple) dans cette image. De la même manière en regardant à l'autre extrémité n є [245,255], il n'y a pas ou peu de pixels blancs. En revanche, le reste de la dynamique est bien réparti. L'image est agréable à l'œil de par sa photométrie, en plus de son contenu.
Pour cette même image, donc pour un même contenu, comprimons la dynamique d'un facteur 2, en divisant l'intensité de chaque pixel de l'image par ce facteur. Nous obtenons une image sombre et faiblement contrastée (figure n° 11 : image (c), histogramme (d)), nettement moins agréable à l'œil. Ajoutons maintenant 128 à la dynamique, en additionnant cette valeur à l'intensité de chacun des pixels de l'image. Nous obtenons une image claire, mais toujours faiblement contrastée, et également nettement moins agréable à l'œil (figure n° 11 : image (e), histogramme (f)).
Nous pouvons conclure très simplement que la qualité visuelle d'une image est intimement liée à l'étendue de sa dynamique, ou à la répartition des niveaux de gris de ses pixels. Une image dont la dynamique est faible est peu contrastée et pas très agréable à l'œil. Pour la rendre plus agréable, il est possible de lui appliquer un traitement dit de Rehaussement des Contrastes.
Nous verrons lors du quatrième article de cette série, intitulé « Première Chaîne Complète de Segmentation » une autre utilisation de l'histogramme, pour déterminer les valeurs de seuil dans une procédure de seuillage.
La réalisation de l'histogramme est obtenue grâce à la commande EdHistogramme qui nécessite le code des parties :
- interface utilisateur, contenu dans le fichier EdHistogramme.c ;
- opérateur, contenu dans le fichier EdLibHistogramme.c.
Les modifications de la dynamique des images ont été réalisées par les commandes contenues dans les fichiers EdDivideDynamic.c et EdTranslateDynamic.c et les traitements dans EdLibPointOperation.c.
Ces opérateurs, comme tous ceux présentés dans la série d'articles sont programmés dans l'Environnement logiciel de Traitement d'Image EdEnviTI, et font partie de la bibliothèque EdVision, disponible sur le site web « Developpez.com ». Le détail des algorithmes et de l'implantation des opérateurs font l'objet des parties II (Algorithme) et III (Implantation) de l'ouvrage : « Les Bases du Traitement d'Image et de la Vision Industrielle et Robotique » disponible sur Lulu.com.
IV-B. Rehaussement des contrastes▲
Le but du rehaussement des contrastes est d'obtenir une image traitée dont la plage de la dynamique s'étale entre 0 et 255. Un certain nombre de méthodes existent dans la littérature.
Dans de nombreux ouvrages, la méthode proposée est celle dite par Égalisation d'Histogramme, basée sur la Théorie de l'Information. Conformément à notre pédagogie, nous avons choisi de présenter la méthode la plus simple mathématiquement et la plus intuitive : Rehaussement Affine. De plus, ses résultats sont tout à fait corrects !
IV-B-1. Plage Utile▲
Pour trouver la plage ou l'étendue de la dynamique des pixels de l'image, une première idée consiste à calculer les valeurs minimale et maximale de l'intensité.
La Plage Utile s'étend de :
Min {I(x,y) / x є [0, ncol - 1], y є[0, nlig - 1]}
à Max {I(x,y) / x є [0, ncol - 1], y є [0, nlig - 1]}
Malheureusement, dans la plupart des images, il y aura toujours un pixel noir à quasiment 0 et un pixel blanc à 255, et l'étendue de la plage trouvée sera 0 - 255. La conclusion sera « Dynamique Correcte », même si en dehors de ces quelques points parasites le reste des valeurs des intensités des pixels reste très concentré, donnant une image sans contraste !
Ainsi, l'idée de la Plage Utile consiste à négliger 2*p pour cent du nombre de pixels : p pour cent foncés, et p pour cent clairs. La Plage utile sera comptabilisée à partir de 100 - 2 x p pour cent des intensités des pixels de l'image (cf. figure n° 12(a)). Elle est déterminée par la valeur des deux bornes n1 et n2, respectivement borne inférieure et supérieure.
IV-B-2. Rehaussement affine des contrastes ▲
Le rehaussement affine revient à effectuer en chaque pixel la modification de la valeur de sa luminance (ou intensité) par la fonction de transfert affine de la figure n° 12 (b)) :
I'(x,y) = 0 si I(x,y) < n1
I'(x,y) = 255 * (I(x,y) - n1) / (n2 - n1) si n1 ≤ I(x,y) ≤ n2
I'(x,y) = 255 si I(x,y) > n2
Pour optimiser le temps de calcul, il faut éviter de calculer en chaque pixel la fonction de transfert ci-dessus nécessitant une multiplication et une division. Pour ce faire, une Table de Transcodage, c'est-à-dire un tableau mono dimensionnel de correspondance entre le niveau n de l'image originale I(x,y) et le niveau n' de l'image aux contrastes rehaussés I'(x,y) est calculé, soit :
Pour tout n Є [0,255], n' = Tab[n]
Ainsi le calcul de la table Tab[n] est effectué pour tout n Є [0,255] une seule fois en début. L'opération de rehaussement affine des contrastes réalisée en chaque pixel P(x,y) consiste à établir la correspondance soit : I'(x,y) = Tab[I(x,y)]
Le rehaussement affine des contrastes est obtenu grâce à la commande EdContrastEnhacement. Le code source de l'interface est contenu dans le fichier EdContrastEnhacement.c, et celui de l'opérateur dans le fichier EdLibPointOperation.c.
IV-B-3. Résultats du rehaussement affine des contrastes▲
Les résultats de l'opérateur de Rehaussement des Contrastes sont présentés sur l'image « Lenna sombre » figure n° 13 (b). Comme 5 % ou 10 % des pixels sombres et clairs vont être négligés, les images résultantes du rehaussement des contrastes, respectivement figures n° 13 (c) et (d) vont être plus contrastées que l'image originale (a) qui ne comportait pas ou très peu de pixels noirs ou blancs.
IV-B-4. Remarque importante▲
Le rehaussement des contrastes n'apporte aucune information supplémentaire à l'image originale peu contrastée. Il présente seulement l'information d'une manière mieux adaptée à la visualisation d'un opérateur(14) . Un tel traitement n'a aucune utilité pour une procédure « automatique » de segmentation, où ce sont les paramètres de contrôle qui doivent s'adapter.
IV-B-5. Exemple d'autres traitements améliorant la visualisation▲
Les images de désert, notamment d'habitations en sable, sont très peu contrastées. Une autre méthode d'améliorer leur visualisation est de renforcer les contours peu marqués en ajoutant à l'image des hautes fréquences. Celles-ci sont obtenues par une détection de la norme du gradient (cf. le cinquième article de la série, intitulé « Segmentation en Contours »). Plusieurs combinaisons d'images renforcées par des hautes fréquences sont présentées au pilote de chasse, qui choisit celle qui lui permet d'accomplir au mieux sa mission.
IV-C. Histogramme couleur▲
L'histogramme d'une image couleur peut être vu comme trois histogrammes précédents, un pour chaque plan spectral : rouge, vert et bleu, cf. figure n° 14 (b).
Les conclusions s'avèrent plus complexes à tirer avec un histogramme couleur. Si nous nous en référons à l'histogramme de l'image de Lenna en couleur, figure n° 14 (b), il ne faudrait pas conclure hâtivement, à la vue des histogrammes des canaux vert et bleu que l'image n'est pas contrastée. En fait, l'image étant rougeâtre - violacée, l'histogramme du canal rouge a lui seul une dynamique correcte.
IV-D. Quantification▲
IV-D-1. Principe▲
La quantification sur n bit (n Є [0,8]) consiste à utiliser n bits pour coder la valeur de la luminance ou de l'intensité du pixel. Pour visualiser l'image quantifiée de manière classique, le codage s'effectue sur les n bits de poids fort d'un octet non signé, les (8 - n) bits de poids faible non utilisés étant mis à zéro.
IV-D-2. Expérimentation▲
Codons l'image de Lenna, initialement sur 8 bits, respectivement sur 7, 6, 5, 4, et 3 bits. La figure n° 15 présente les images quantifiées obtenues, ainsi qu'à titre de vérification l'histogramme correspondant.
Un codage sur 7 bits consiste à n'utiliser qu'un niveau de gris sur 2, - sur 6 bits : 1 sur 4, - sur 5 bits : 1 sur 8, - sur 4 bits : 1 sur 16 et enfin - sur 3 bits : 1 sur 32. Cette propriété se traduit sur l'histogramme par des raies (niveaux de gris utilisés) de plus en plus espacées.
Jusqu'à un codage sur 5 bits, notre œil ne voit pas la différence entre le codage sur n bits et l'image originale sur 8. Pour n = 4, la différence devient visible, notamment au niveau des dégradés des niveaux de gris sur le front et sur l'épaule. Pour n = 3 cette différence devient « gênante » à l'œil.
En conclusion : notre œil ne voit pas 256 niveaux de gris. Les bits de poids faible écrasés pourraient être utilisés à véhiculer une autre information, tel qu'un tatouage (trop) simple. Dans le cadre de la Robotique Mobile téléopérée, un codage sur 4 bits réduit d'un facteur 2 le nombre de données à transmettre, d'une manière simple à mettre en œuvre, sans pour autant gêner le téléopérateur.
La quantification est obtenue grâce à la commande EdQuantization. Le code source de l'interface est contenu dans le fichier EdQuantization.c, et celui de l'opérateur dans le fichier EdLibPointOperation.c.
IV-E. Réduction/zoom▲
Nous allons examiner comment il est possible de réduire (effet de réduction) ou d'augmenter (effet de zoom) la résolution de l'image. Nous montrerons la possibilité d'utiliser ces deux effets, en les combinant pour effectuer une compression/décompression de l'image pour la transmission et/ou le stockage. Nous examinerons également les pertes, en termes de qualité visuelle, relatives à ces deux opérations.
De manière à ne pas déformer le contenu géométrique de l'image, nous choisirons le même facteur de réduction ou de zoom sur les lignes et colonnes. De plus nous choisirons ce facteur entier. Nous commencerons par la réduction, de loin l'opération la plus simple.
IV-E-1. Réduction▲
La réduction d'un facteur red consiste à ne conserver qu'une ligne et qu'une colonne sur red, les images pouvant être de taille quelconque. La figure n° 16 présente une réduction d'un facteur 3. Ainsi un carré de 3 x 3 pixels va être remplacé par un seul pixel.
Nous proposons deux algorithmes :
- par sous-échantillonnage ;
- par moyenne locale de la zone.
La réduction par Sous-Échantillonnage est l'algorithme le plus simple de réduction. Elle consiste à ne garder la valeur de l'intensité que d'un seul pixel de l'image originale pour la zone correspondante, d'extension red x red pixels. Le plus simple est de ne garder que les pixels de l'image originale dont les numéros de lignes et de colonnes sont multiples entiers de red, c'est-à-dire le pixel en haut et à gauche de la zone concernée. Prendre un autre pixel, tel que le pixel central, ne change pas fondamentalement le résultat obtenu.
La réduction par Moyenne locale de la zone (ou plus simplement par Moyennage) consiste à effectuer la moyenne des intensités des pixels de l'image originale pour la zone correspondante, d'extension red x red pixels.
La zone à moyenner sur l'image originale s'étend :
- de x_red x red à (x_red + 1) x red - 1 sur x ;
- de y_red x red à (y_red + 1) x red - 1 sur y.
De manière à pouvoir réduire par moyenne locale une image par un facteur entier, quelle que soit la taille de l'image, et quel que soit le facteur de réduction, il faut vérifier que cette zone ne sorte pas de l'image source.
Remarque
C'est cette seconde réduction, par moyenne locale, qui simule le mieux les résultats obtenus par un capteur moins résolu. En effet, chaque pixel du capteur moins résolu intègre sur le champ de vue de plusieurs pixels d'un capteur plus résolu.
Résultats
La figure n° 17 présente les résultats d'une réduction d'un facteur 2 puis 4, sur l'image de Lenna. Les réductions sous échantillonnées (b) et (d) apparaissent plus bruitées que les réductions moyennées (c) et (e), donc plus désagréables à l'œil.
En effet, les pixels de l'image réduite sont à la résolution de l'image initiale, et l'information intermédiaire est enlevée par sous-échantillonnage. Alors que par moyenne locale, les pixels intègrent toute l'information en la dégradant.
Les réductions par sous-échantillonnage et moyenne sont obtenues par la commande EdReduction. Le code source de l'interface est contenu dans le fichier EdReduction.c, et celui des opérateurs dans le fichier EdLibReduction.c.
IV-E-2. Zoom▲
L'opérateur de Zoom Numérique est l'opérateur « dual »(15) de l'opérateur de Réduction. Il consiste à créer une image plus grande, à partir d'une image plus petite (cf. figure n° 18). De manière à ne pas déformer le contenu géométrique de l'image, nous choisirons le même facteur de zoom sur les lignes et colonnes.
Ainsi, pour deux des trois zooms présentés, l'opérateur va recréer (nZoom -1) lignes par ligne de l'image à zoomer et (nZoom - 1) colonnes par colonne, nZoom étant le facteur de zoom (cf. les pixels marqués d'une croix « x » figure n° 18). Les images peuvent être de taille quelconque.
Il ne faut pas confondre le Zoom Numérique avec le Zoom Optique. En effet, le zoom numérique ne crée pas de nouvelle information : il n'apporte pas de détail à l'image, il grossit l'existant. En changeant la focale, le zoom optique apporte lui, par contre, de nouveaux détails.
Trois zooms numériques sont présentés :
- le premier : le plus simple, par Duplication du pixel. Il suffit de dupliquer le pixel de l'image originale ou à zoomer sur une zone de nZoom colonnes x nZoom lignes (cf. figure n°19 (a)) ;
-
les deux autres, par interpolation. La valeur du pixel de l'image zoomée dépend de la valeur de ses voisins. Les deux interpolations, classées par complexité croissante sont :
- par Interpolation au plus proche voisin : seul le voisin le plus proche des 4 (cas le plus général) est pris en compte. Deux implantations sont possibles : comme pour la duplication du pixel (cf. figure n° 19 (b)), ou en version simplifiée de l'interpolation bilinéaire (cf. figure n° 19 (c)),
- par Interpolation Bilinéaire : l'interpolation prend en compte les 4 voisins (maille carrée) dans le cas général, 2 ou 1 dans les cas particuliers. La bilinéarité signifie que le pixel de l'image zoomée est obtenu par combinaison linéaire des 4 pixels voisins selon Ox et Oy de l'image originale (cf. figure n° 19 (d)).
L'interpolation par approximation au plus proche voisin revient également à une duplication du pixel de l'image à zoomer (cf. figure n° 19). Seule l'approximation bilinéaire présente de meilleurs résultats visuels.
Pour les trois opérateurs, le principe consiste à créer l'image zoomée, c'est-à-dire à calculer la valeur de l'intensité de chacun de ses pixels en :
- calculant la position correspondante du pixel dans l'image à zoomer ;
- en utilisant ensuite la méthode d'approximation ad hoc.
Calcul de la position correspondante du pixel de l'image zoomée dans l'image à zoomer :
La figure n° 20 (a) présente le contexte. Soit le pixel P(xZoom,yZoom) de l'image zoomée xZoom et yZoom sont des coordonnées entières), et sa position PR(xR,yR) dans l'image à zoomer où ses coordonnées xR et yR sont des nombres réels.
Soient les 4 pixels (i.e. à coordonnées entières) les plus proches, de l'image à zoomer :
P0(xRInit,yRInit), P1(xRInit + 1,yRInit), P2(xRInit,yRInit + 1) et P3(xRInit+1,yRInit+1).
Soient (a, b) Є [0,1[2. Les relations entre ces divers paramètres sont :
- xR = xZoom / nZoom // Division en nombres réels
- yR = yZoom / nZoom // Idem
- xRInit = xZoom / nZoom // Division en nombres entiers (= E(xR)c'est-à-dire la partie entière)
- yRInit = yZoom / nZoom // Idem
- a = xR - xRInit
- b = yR - yRInit
Calcul de l'intensité dans l'image zoomée Iz(xZoom,yZoom) :
Il va dépendre de l'opérateur. Pour l'opérateur par duplication du pixel : Iz(xZoom,yZoom) = I(xRInit,yRInit)
Pour l'opérateur par interpolation au plus proche voisin, implanté comme pour une interpolation bilinéaire (cf. figure n° 19) :
Pour l'opérateur par interpolation bilinéaire : dans le cas général, les quatre plus proches voisins sont pris en considération, ainsi que leur distance selon les axes Ox et Oy au point à créer. Leur pondération va être d'autant plus importante que le voisin est proche.
Ainsi si a (a Є [0,1[) est la distance, (1 - a) va être la pondération.
Ainsi, si a = 0 ou si b = 0, seuls deux voisins sont pris en considération pour le calcul. Si a = 0 et b = 0, le point à créer de l'image zoomée se trouve physiquement sur le point de l'image à zoomer sa pondération sera de 1.
La formule de interpolation Bilinéaire est la suivante :
La figure n° 21 présente les résultats des opérateurs de zoom d'un facteur 2 sur l'image de Lenna. La difficulté est que les images sont réduites pour être présentées, ce qui estompe ce qui va être dit.
Nous pouvons conclure sur le peu de différence entre le zoom par duplication du pixel et le zoom par interpolation au plus proche voisin. Tous deux génèrent un effet de crénelure ou d'aliasing, visible notamment sur les bords du chapeau et de l'épaule de Lenna.
Le Zoom par interpolation bilinéaire assure une meilleure qualité du rendu : l'effet précédent est estompé.
Les zooms par duplication et interpolations au plus proche voisin et bilinéaires sont obtenus par la commande EdZoom. Le code source de l'interface est contenu dans le fichier EdZoom.c, et celui des opérateurs dans le fichier EdLibZoom.c.
Combinaison réduction / zoom :
La figure n° 22 présente les diverses combinaisons d'une réduction suivie d'un zoom.
Les deux types de réduction
- par sous-échantillonnage,
- par moyenne locale,
sont associés aux deux types de zoom
- par duplication du pixel,
- par interpolation bilinéaire.
ce qui représente quatre combinaisons possibles, que l'on peut utiliser, par exemple pour comprimer (par réduction) les données images pour une transmission ou un stockage, et les restituer par zoom.
La réduction d'un facteur 2 présentée figure n° 22, a un taux de compression de 4 (soit 2x2). Le zoom présenté a également un coefficient de 2, ce qui permet de revenir à la résolution de l'image originale.
Il est ainsi possible d'évaluer la perte en termes de qualité visuelle après une procédure de compression/décompression, par rapport à l'image originale.
La conclusion est évidente : la meilleure des réductions (par moyenne locale) associée au meilleur des zooms (par interpolation bilinéaire) donne de loin la meilleure restitution (image en bas à droite). Même pour la meilleure restitution, nous constatons la perte des détails, en comparant le résultat de la réduction suivie d'un zoom, à l'image originale. En effet, les détails perdus lors de la réduction ne sont pas recréés par le zoom numérique.
Combinée à la compression par quantification précédemment présentée, on obtient un taux de compression de 8, avec des algorithmes très simples et très rapides sur le plan de l'exécution.
IV-F. Négatif▲
L'Opérateur de Négatif, par référence aux films négatifs des appareils photo argentiques, ou d'Inversion Vidéo consiste à inverser en chaque pixel les niveaux de gris clairs en foncés et réciproquement. La formule mathématique est :
N(x,y) = 255 - I(x,y)
où I(x,y) est l'image originale, et N(x,y) l'image « négatif ».
Il en est de même en imagerie couleur RVB, où l'inversion précédente est effectuée en chaque canal R, V et B ainsi :
NR(x,y) = 255 - IR(x,y)
NV(x,y) = 255 - IV(x,y)
NB(x,y) = 255 - IB(x,y)
où IR(x,y), IV(x,y) et IB(x,y) sont les composantes sur les plans rouge, vert et bleu de l'image originale, et NR(x,y), NV(x,y) et NB(x,y) de l'image « négatif ».
Les résultats de l'opérateur négatif ou de l'inversion vidéo en imagerie N&B et couleur RVB sont présentés figure n° 23.
Les opérateurs négatifs en imagerie N&B et couleur sont obtenus par la commande EdReverse. Le code source de l'interface est contenu dans le fichier EdReverse.c, et celui des opérateurs dans le fichier EdLibPointOperation.c.
V. Opérateurs linéaires et non linéaires▲
V-A. Principe▲
Le principe d'un opérateur linéaire consiste à affecter au pixel courant dans l'image résultat, une combinaison linéaire des intensités des pixels de son voisinage dans l'image source. Le voisinage peut être de taille et de forme quelconques. Comme nous l'avons précédemment énoncé nous nous limiterons au voisinage 3 x 3 centré. L'extension à tout autre voisinage peut être considérée simplement.
Prenons deux réels : x et y. Toute combinaison linéaire de x et y s'exprime de la manière suivante :
a et b sont les deux coefficients de la combinaison linéaire.
Pour le voisinage 3 x 3 centré, la combinaison linéaire porte sur neuf intensités. Les neuf coefficients de la combinaison linéaire sont regroupés au sein d'un masque de convolution(16)
V-B. Formulation mathématique▲
La valeur du pixel résultat F(x,y) est obtenue à partir d'une combinaison linéaire des valeurs des intensités des pixels du voisinage de l'image source I(x,y) par le Produit de Convolution de l'image I(x,y) par le masque C(i,j). La formulation mathématique est :
Un opérateur est dit « Non Linéaire » s'il ne peut pas se mettre
sous la forme ci-dessus.
Les opérateurs de Morphologie Mathématique, sur images binaires (cf. article n° 4 de la série), ainsi que le filtre Lisseur Médian (plus loin dans cet article) sont des filtres non linéaires.
La figure n° 24 permet de mieux visualiser la formule de la convolution. Par pixel, sont effectuées
- neuf multiplications entre les coefficients de la combinaison linéaire, regroupés au sein d'un masque de convolution, et les intensités des pixels,
- huit additions entre les produits
à l'exception des bords de l'image :
L'opérateur de convolution est obtenu par la commande EdConvolution. Le code source de l'interface est contenu dans le fichier EdConvolution.c, et celui de l'opérateur dans le fichier EdLibConvolution.c.
Étant donné que les opérateurs linéaires usuels ont des masques de convolution comportant des coefficients 0, +/- 1, +/- 2 et que la multiplication est une opération coûteuse en temps de calcul, cet opérateur générique est très peu utilisé. Il est préférable de « coder en dur » de manière optimale chaque opérateur.
Sur une zone homogène de l'image, c'est-à-dire :
la valeur du pixel résultat devient :
où S est la somme des coefficients du filtre :
Ce résultat important que nous démontrons dans la partie II de notre ouvrage est utilisé pour justifier :
- la normalisation des masques des filtres linéaires de Lissage ;
- ainsi que la forme des masques des filtres linéaires réalisant la projection du vecteur gradient.
VI. Opérateurs de lissage d'image▲
VI-A. Notion de bruit dans les images▲
D'une manière idéale, l'image est constituée de zones homogènes (c'est-à-dire d'intensité constante), projection dans l'image des objets 3D de la scène, et de zones de transition entre les zones homogènes d'extension filiforme, projection dans l'image des contours internes ou externes des objets 3D de la scène. C'est du moins ce que nous voyons, nous, êtres humains, notre vision étant également le fruit de l'interprétation par notre cerveau.
En revanche l'image numérique issue de la caméra est différente. Une zone pourtant homogène à l'œil sur l'image, n'est pas uniforme en valeurs. Les raisons de cette différence peuvent être diverses et variées :
- l'objet n'est pas réellement homogène : par exemple lorsqu'un mur interprété en tant que tel par notre cerveau comporte des salissures ;
- l'éclairage n'est pas homogène : par exemple l'éclairage produit par un tube à néon fixé « horizontalement » au plafond est plus intense en haut du mur vertical, qu'en bas ;
- les capteurs (CCD, CMOS, autres) ont des pixels dont les dynamiques sont différentes. À cela, ajoutons les bruits classiques de l'électronique, ainsi que de la quantification.
L'importance de la composante de bruit va dépendre du type de caméra, de sa qualité, et aussi de l'éclairage. Une prise de vue dans une zone sombre où le contrôle automatique de gain amplifie plus sera plus entachée de bruits.
De même, une image en infrarouge thermique, comme une image d'échographie ultra sonore, ou une image radar, seront plus bruitées que de simples images dans le visible en N&B ou en couleur RVB.
VI-B. Visualisation du bruit dans les images▲
Plutôt que de trouver un modèle mathématique, ce que font la plupart des ouvrages, nous préférons l'observer, en tant que physicien. Le bruit s'observe plus particulièrement dans les zones claires de l'image, car notre œil effectue une compression « logarithmique » des niveaux de gris(17).
Pour cela, nous allons introduire la notion de Profil horizontal ou vertical, c'est-à-dire la courbe représentant l'intensité dans l'image selon une ligne (profil horizontal) ou selon une colonne (profil vertical).
Regardons l'image du bureau présenté figure n° 25 (a), et les niveaux de gris du profil horizontal (b), représentant la ligne en couleur blanche sur l'image. On reconnaît bien sur la gauche de l'image les carreaux noirs, et les montants de fenêtre plus clairs. Il faut au contraire se placer à droite de l'image pour observer le bruit.
Le profil horizontal passe par des zones « claires » homogènes à l'œil. Pourtant, le tracé des valeurs du profil (b) montre bien une certaine dispersion des niveaux de gris.
Les figures n° 25 (c) et (d) sont un gros plan sur la zone d'intérêt, comportant du bruit.
VI-C. Nécessité des opérateurs de lissage ▲
Le problème n'est pas pour un opérateur humain, mais pour les traitements automatiques de segmentation d'image qui extraient soit :
- les zones homogènes : appelées Régions ;
- les zones de transition, d'extension filiforme : appelées Contours.
Le but des traitements automatiques est d'obtenir des résultats semblables à la vision d'un opérateur humain. Ainsi, la présence d'une composante importante de bruit va pénaliser considérablement leurs résultats, d'où la nécessité d'utiliser au préalable un opérateur de lissage d'image, dont le rôle sera de diminuer la composante de bruit, mais sans trop altérer l'image.
Un certain nombre d'algorithmes réalisant la fonctionnalité de Lissage d'Image sont proposés dans la littérature.
Nous en présenterons cinq. Ainsi, trois algorithmes classiques seront détaillés, les deux autres seront présentés à titre plus anecdotique. Il s'agit des filtres suivants, classifiés selon leur type :
-
lissages linéaires :
- lissage moyen,
- lissage gaussien ;
-
lissages non linéaires :
- lissage médian,
- lissages de Nagao : moyen, et médian.
Pour mieux apprécier et comparer visuellement les résultats des cinq opérateurs, effectuant la même fonctionnalité de Lissage, leurs résultats seront évalués sur des images bruitées, avec un bruit dit poivre et sel aléatoire (cf. Figure n° 26).
Pour les images du bureau et de Lenna, 500 positions (x,y) ont été tirées aléatoirement, avec une valeur également aléatoire de la luminance. Ce bruit, localisé en un petit nombre de pixels qui « choquent » parfois par rapport à leur entourage, est particulièrement bien visible.
VI-D. Lissages linéaires▲
VI-D-1. Condition portant sur le filtre lisseur linéaire▲
Pour un lissage linéaire, comme pour tout autre lissage, une zone homogène est exempte de bruit. Elle doit par conséquent rester inchangée à l'issue du lissage. Cette condition a des répercussions sur les coefficients du masque de convolution, dont la somme des coefficients doit être égale à 1, soit :
VI-D-2. Filtre moyen▲
Principe
Le filtre moyen affecte au pixel courant la moyenne des intensités de son voisinage(18)
Ceci revient à effectuer une convolution, soit neuf multiplications et huit additions par pixel (sauf les bords), avec le masque ci-dessous, comportant une normalisation par un facteur valant 9.
Pourquoi « revient » ? Parce qu'une telle implantation serait ridicule, car d'une part une multiplication prend du temps, et d'autre part une multiplication par 1 est inutile. Le masque du lisseur moyen est :
Mais le calcul, effectué en chaque pixel est le suivant :
Cette formule est celle qui minimise le nombre de divisions. Elle revient bien à la convolution avec le masque précédemment présenté. On note également que la somme des coefficients du masque, normalisation incluse, est égale à l'unité, condition nécessaire d'un lisseur linéaire.
Le lissage moyen est obtenu par la commande EdMeanFiltering. Le code source de l'interface est contenu dans le fichier EdMeanFiltering.c, et celui de l'opérateur dans le fichier EdLibMeanFiltering.c.
VI-D-3. Filtre gaussien▲
Principe
Le filtre gaussien affecte au pixel courant la gaussienne des intensités de son voisinage.
Une gaussienne est une courbe en cloche (cf. figure n° 27) d'équations en 1D et 2D :
Le paramètre s est proportionnel à la largeur de la courbe à mi-hauteur LH/2, plus exactement :
Une gaussienne peut être approximée en 1D par le masque [1 2 1]. Voici un masque approximant cette gaussienne en 2D :
La différence avec le lissage moyen est la pondération des pixels du voisinage 3 x 3 centré. En effet, pour le lissage moyen, la pondération de tous les pixels du voisinage est identique. Pour le lissage gaussien, le pixel central, c'est-à-dire là où l'on effectue le calcul, a une pondération supérieure. Le lisseur gaussien va de ce fait moins lisser que le lisseur moyen.
Cette différence suggère également une possibilité d'implantation, qui consiste à ajouter la valeur du pixel central du voisinage (ou courant) au calcul de la moyenne des intensités du voisinage, et ensuite de normaliser par 10 au lieu de 9, ce qui respecte la contrainte d'un lisseur linéaire.
La formule employée est alors la suivante :
Le lissage gaussien est obtenu par la commande EdGaussianFiltering. Le code source de l'interface est contenu dans le fichier EdGaussianFiltering.c, et celui de l'opérateur dans le fichier EdLibGaussianFiltering.c.
VI-E. Lissages non linéaires▲
VI-E-1. Filtre médian▲
Principe
Le filtre médian affecte au pixel courant la médiane des intensités de son voisinage.
La valeur médiane d'un ensemble de valeurs est la valeur pour laquelle, il y autant de valeurs plus grandes que de valeurs plus petites. Pour cela, l'algorithme (cf. figure n° 28) consiste à ranger les valeurs du voisinage dans un tableau mono dimensionnel, car plus facile à trier, et à le trier. Dans le cas du voisinage 3 x 3 le tableau Tab comportera neuf valeurs de Tab[0] à Tab[8](19). La valeur médiane, une fois le tableau trié est la cinquième, soit Tab[4], quel que soit l'ordre du tri : croissant ou décroissant.
La méthode de tri importe peu. Il existe certes des méthodes dites de Tri Rapide ou Quick Sort qui sont bien plus rapides lorsque le nombre de valeurs à trier est très important. Ici, pour neuf valeurs, nous suggérons la méthode simple du Tri à Bulle qui est la matérialisation du théorème mathématique :
« Toute Permutation(20) peut être réalisée sous forme de Transpositions (21) »
Le principe du Tri à Bulle consiste à parcourir le tableau, en considérant à chaque étape l'élément courant indicé k et suivant indicé (k+1). Les éléments sont transposés s'ils ne sont pas dans le bon ordre : par exemple si Tab[k] > Tab[k+1]. Un nouveau parcours du tableau est entrepris, si au moins une permutation a été réalisée lors du parcours précédent. Le tri s'arrête ainsi naturellement à la suite d'un parcours n'ayant donné lieu à aucune transposition.
Le filtre médian fait partie des filtres d'ordre comme les filtres Maximum et Minimum dont le principe est d'affecter au pixel courant les valeurs maximale et minimale des intensités du voisinage.
Le lissage médian est obtenu par la commande EdMedianFiltering. Le code source de l'interface est contenu dans le fichier EdMedianFiltering.c, et celui de l'opérateur dans le fichier EdLibMedianFiltering.c.
VI-F. Comparaison des trois lissages : moyen, médian, gaussien▲
VI-F-1. Comparaison sur un exemple 1D▲
Examinons le comportement des opérateurs lisseurs moyen et médian sur des profils 1D de la figure n° 29. La moyenne ou la médiane sont calculées au point courant du profil 1D, en tenant compte des points précédent et suivant. Pour le filtre médian 1D sur un voisinage comportant trois valeurs, dès que deux des trois valeurs sont égales, la valeur médiane prend cette valeur commune.
Le comportement du filtre moyen est le suivant :
- le bruit est réduit en intensité, mais sa localisation est élargie ;
- la transition est également élargie. C'est l'effet de flou que nous visualiserons sur les images, au niveau des contours des objets.
Le comportement du filtre médian est le suivant :
- le bruit incohérent avec le reste du voisinage est purement et simplement entièrement supprimé. L'effet est parfait !
- la transition est inchangée. Ceci nous permet d'affirmer que le filtre médian ne floute pas les images.
VI-F-2. Comparaison sur les images bruitées▲
Nous retrouvons également sur les images du bureau (cf. figure n° 30) et de Lenna (cf. figure n° 31) les conclusions énoncées ci-dessus. Nous comparons l'effet des trois filtrages : moyen (b), gaussien (c), et médian (d).
Pour comprendre les différents effets, que nous allons lister, il faut regarder à des endroits bien précis de l'image :
- la Réduction du Bruit : regarder les images dans leur globalité ;
- le Flou : regarder les contours des fenêtres pour l'image du bureau, le bord du chapeau, et le contour de l'épaule pour l'image de Lenna ;
- la Disparition des Détails , à ne pas assimiler à l'effet de flou. Il faut regarder les plumes, et le tissu du chapeau, sur l'image de Lenna.
Le filtre moyen (b) réduit « l'intensité » de la composante de bruit dans les images, mais il « étale » le bruit sur les pixels voisins.
Le filtre moyen étale les contours : il les floute. C'est un effet indésirable pour une chaîne de traitements automatiques, dont les étapes suivantes sont une segmentation en contours ou en régions. En effet, le flou diminue l'amplitude du contour, et réduit le contraste local entre les régions, ce qui pénalise les opérateurs de segmentation en Contours, et également en Régions. En revanche, c'est l'effet recherché par le graphiste qui cherche à réaliser une image artistique, par exemple d'un visage net avec un arrière-plan flou.
Le filtre gaussien (c) a un comportement semblable au filtre Moyen, mais légèrement moins accentué. Il filtre moins le bruit, et floute moins les contours, car il accorde une pondération plus importante au pixel central.
Ainsi grâce à ces opérateurs lisseurs moyen et gaussien(22) et au flou qu'ils induisent, il est possible en post traitement de réaliser un flou de défocalisation, bien connu des photographes, qui consiste à faire la mise au point sur le sujet, en utilisant un grand diaphragme (ouverture maxi = nombre mini), donc une faible profondeur de champ. Ainsi, tout objet dans un plan autre que le sujet sera flou.
Une différence fondamentale : le flou numérique est le même dans toute l'image. Ainsi, en retouche d'images, il est possible de :
- masquer le sujet, par un détourage manuel. Le flou ne s'appliquera pas sur le sujet ;
- combiner plusieurs opérateurs avec des flous plus ou moins marqués, en fonction de la distance (dans l'image) au sujet.
Le filtre médian ne floute pas les contours. C'est flagrant sur l'image du bureau (figure n° 30), où les contours sont nets, même plus que sur l'image originale. Le filtre médian est même qualifié parfois dans certains ouvrages d'être renforçateur des contours.
En revanche l'image de Lenna traitée par le filtre médian (cf. figure n° 31) paraît floue. En fait, il ne s'agit pas d'un effet de flou au sens précédemment énoncé, c'est-à-dire un élargissement de la zone de transition.
En effet, le filtre médian enlève les petits détails qui sont incohérents avec le reste du voisinage. Il ne fait bien évidemment pas la distinction entre le bruit et les petits détails. Ainsi, la perte d'un certain nombre de petits détails des plumes du chapeau explique cette sensation visuelle.
VI-F-3. Comparaison sur les profils des images ▲
Nous retrouvons tous les éléments précédemment mentionnés sur la figure n° 32 des profils de l'image du bureau. L'effet de lissage est bien meilleur avec le lisseur médian qu'avec les lisseurs moyen et gaussien. Pour s'en convaincre, il faut regarder par exemple la partie cerclée de l'image (a). L'intensité sur l'image filtrée est bien plus constante avec le filtre médian.
VI-G. Les Lissages non linéaires de Nagao▲
VI-G-1. Principe▲
Les neuf voisinages de Nagao, extraits du voisinage 5 x 5 :
Neuf voisinages sont extraits du voisinage 5 x5 centré (cf : figure n° 33)
- quatre cardinaux : nord, sud, est, ouest ;
- quatre diagonaux : nord-est, nord-ouest, sud-est, sud-ouest ;
- central.
Le filtre de Nagao moyen (respectivement médian) affecte au pixel courant la moyenne (resp. la médiane) du voisinage ayant la plus faible variance.
Nous présentons cet algorithme pour montrer un exemple de voisinages non 3 x 3 centrés.
Algorithme
L'algorithme du filtre de Nagao moyen (resp. médian) est présenté ci-dessous :
Effet
Comme pour le filtre lisseur médian, cf. figure n° 34 le bruit impulsionnel incohérent avec son voisinage a totalement disparu. En revanche, l'image est modifiée. En propageant la valeur moyenne ou médiane du voisinage directionnel de plus faible écart-type, le filtre lisseur de Nagao propage les intensités des régions, et diminue la largeur de la zone de transition. Il renforce ainsi les contours. Il est qualifié dans la littérature de filtre renforçateur des contours.
Retrouvons cette propriété sur les profils de la figure n° 35. Le lissage a un effet plus accentué pour les filtres de Nagao, que pour le filtre lisseur médian.
Les lissages de Nagao moyen et médian sont obtenus par la commande EdNagaoFiltering. Le code source de l'interface est contenu dans le fichier EdNagaoFiltering.c, et celui des opérateurs dans le fichier EdLibNagaoFiltering.c.
Compte tenu de la quantité de calculs à effectuer en chaque pixel (à l'exception des bords : i.e. quatre lignes et quatre colonnes ne sont pas traitées), la réalisation des filtres de Nagao n'est pas « immédiate », même pour une image de faible résolution, par exemple l'image du bureau de résolution 256 x 256.
VII. Conclusion▲
Au cours de ce second article, nous avons commencé par étudier en détail l'algorithme puis l'implantation en langage C dans l'environnement logiciel de traitement d'image EdEnviTI des deux mécanismes de base : le balayage vidéo simple de l'image et le balayage vidéo avec examen du voisinage 3 x 3 centré, nous présentons leurs applications au travers d'un certain nombre d'opérateurs.
Ensuite, nous avons vu les algorithmes
- de Visualisation d'Images : Histogramme, Rehaussement des Contrastes, Quantification, Réduction, Zoom,
- des opérateurs linéaires non linéaires,
- des opérateurs réalisant la fonctionnalité de Lissage d'Image : linéaires : opérateurs moyen et gaussien, non linéaires : opérateurs médian et de Nagao (moyen et médian),
et évalué leurs résultats, de manière comparative lorsque plusieurs opérateurs réalisaient la même fonctionnalité (réduction, zoom, et lissage d'image).
Dans le sixième et dernier article de cette première série, nous détaillerons la programmation, dans l'environnement logiciel de Traitement d'Image EdEnviTI, de l'opérateur de Lissage Moyen, et verrons comment créer rapidement un nouvel opérateur à partir de cet exemple. Ainsi, un lecteur soucieux de mettre ses nouvelles connaissances en application pourra programmer les opérateurs de ce chapitre, et comparer ses propres codes source avec ceux de la bibliothèque EdVision.
Enfin, dans l'article suivant, troisième de la série intitulé « Introduction aux Différents Types de Segmentation », nous étudierons les différentes manières d'extraire les informations de l'image et de les exploiter. Au cours du quatrième, intitulé « Première Chaîne Complète de Segmentation », nous reviendrons sur le détail des opérateurs, comme dans ce chapitre.
VIII. Remerciements▲
Je tiens à remercier chaleureusement l'ensemble du Comité de Rédaction de « Developpez.com », et tout particulièrement Francis Walter pour ses précieux conseils et encouragements, Claude Leloup pour sa minutieuse relecture orthographique et typologique, Djibril et f-leb pour leur aide à la mise en forme et utilisation des divers outils d'écriture. Merci à tous pour votre professionnalisme, votre réactivité et votre confiance. Cela a été un plaisir de travailler avec vous.