Traitement de l’image

La beauté est dans l’œil de celui qui regarde.”
Oscar Wilde

  1. Le codage des couleurs

Il existe plusieurs façons de coder les couleurs. Nous en présentons ici deux : le système RVB et le système CMJN. Le système CMJN est utilisé pour l’impression, tandis que le système RVB est utilisé pour la lumière (écran, projecteurs, …).

                   CMJN

                   RVB

1.1. Le système RVB

Il existe plusieurs façons de décrire les couleurs en informatique. Nous présentons ici une des plus utilisées : le codage RVB, qui est utilisé notamment dans les formats d’image JPEG et TIFF. Rouge vert bleu, abrégé RVB (ou RGB de l’anglais red, green, blue), est un format de codage des couleurs. Ces trois couleurs sont les couleurs primaires en synthèse additive. Elles correspondent en fait à peu près aux trois longueurs d’ondes auxquelles répondent les trois types de cônes de l’œil humain (voir trichromie). L’addition des trois donne du blanc pour l’œil humain. Elles sont utilisées en éclairage afin d’obtenir toutes les couleurs visibles par l’homme. Elles sont aujourd’hui utilisées en vidéo, pour l’affichage sur les écrans, et dans les logiciels d’imagerie. C’est sur ce principe que fonctionnent les téléviseurs couleur. Si vous regardez un écran de télévision couleur avec une loupe, vous allez voir apparaître des groupes de trois points lumineux : un rouge, un vert et un bleu. La combinaison de ces trois points donne un point lumineux (un pixel) d’une certaine couleur. Le système RVB est une des façons de décrire une couleur en informatique. Ainsi le triplet {255, 255, 255} donnera du blanc, {255, 0, 0} un rouge pur, {100, 100, 100} un gris, etc. Le premier nombre donne la composante rouge, le deuxième la composante verte et le dernier la composante bleue.

couleur3couleur4

1.2. Le cube des couleurs

On peut représenter chacune de ces couleurs comme un point d’un cube de l’espace de dimension trois en considérant un repère orthonormé dont les trois axes r, g, b représentent les intensités de rouge, de vert et de bleu. L’origine représente ainsi le noir (r=g=b=0) et le point opposé (r=g=b=255) le blanc. Les trois sommets (255,0,0), (0,255,0) et (0,0,255) représentent les trois couleurs de base (rouge, vert, bleu) et les trois sommets opposés, (0,255,255), (255,0,255) et (255,255,0), le cyan, le magenta et le jaune. La grande diagonale de ce cube joignant le noir et le blanc est l’axe achromatique, i.e. l’axe des niveaux de gris.

cube-des-couleurs

Le cube des couleurs

1.3. Le système CMJN

 

La quadrichromie ou CMJN (cyan, magenta, jaune, noir ; en anglais CMYK, cyan, magenta, yellow, key) est un procédé d’imprimerie permettant de reproduire un large spectre colorimétrique à partir des trois teintes de base (le cyan, le magenta et le jaune ou yellow en anglais) auxquelles on ajoute le noir (key en anglais). L’absence de ces trois composantes donne du blanc tandis que la somme des trois donne du noir. Toutefois, le noir obtenu par l’ajout des trois couleurs Cyan, Magenta et Jaune n’étant que partiellement noir en pratique (et coûtant cher), les imprimeurs rajoutent une composante d’encre noire.

cmjn

CCyan (0,255,255)
MMagneta (255,0,255)
JJaune (255,255,0)
NNoir (0,0,0)

  1. Formats d’images

 On désigne sous le terme d’image numérique toute image acquise, créée, traitée ou stockée sous forme binaire.

2.1. Images matricielles (bitmap)

Elles sont composées, comme leur nom l’indique, d’une matrice (tableau) de points colorés. Dans le cas des images à deux dimensions (le plus courant), les points sont appelés pixels. Ce type d’image s’adapte bien à l’affichage sur écran informatique ; il est en revanche peu adapté pour l’impression, car la résolution des écrans informatiques, généralement de 72 à 96 ppp (« points par pouce », en anglais dots per inch ou dpi) est bien inférieure à celle atteinte par les imprimantes, au moins 600 ppp aujourd’hui. L’image imprimée, si elle n’a pas une haute résolution, sera donc plus ou moins floue ou laissera apparaître des pixels carrés visibles. Les formats d’images matricielles les plus courants sont jpeg, gif, png, tiff, bmp.

exemple-dimagematricielle

Exemple d’image matricielle

Définition et résolution :

La définition d’une image matricielle est donnée par le nombre de points la composant. En image numérique, cela correspond au nombre de pixels qui composent l’image en hauteur (axe vertical) et en largeur (axe horizontal) : 200 pixels x 450 pixels par exemple. La résolution d’une image matricielle est donnée par un nombre de pixels par unité de longueur (classiquement en ppp). Ce paramètre est défini lors de la numérisation (passage de l’image sous forme binaire), et dépend principalement des caractéristiques du matériel utilisé lors de la numérisation. Plus le nombre de pixels par unité de longueur de la structure à numériser est élevé, plus la quantité d’information qui décrit cette structure est importante et plus la résolution est élevée. La résolution d’une image numérique définit donc le degré de détail de l’image. Ainsi, plus la résolution est élevée, meilleure est la restitution. Cependant, pour une même dimension d’image, plus la résolution est élevée, plus le nombre de pixels composant l’image est grand. Le nombre de pixels est proportionnel au carré de la résolution, étant donné le caractère bidimensionnel de l’image : si la résolution est multipliée par trois, le nombre de pixels est multiplié par neuf. Augmenter la résolution peut entraîner des temps de visualisation et d’impression plus longs, et conduire à une taille trop importante du fichier contenant l’image et à de la place excessive occupée en mémoire.

2.2. Images vectorielles

Le principe des images vectorielles est de représenter les données de l’image par des formules géométriques qui vont pouvoir être décrites d’un point de vue mathématique. Cela signifie qu’au lieu de mémoriser une mosaïque de points élémentaires, on stocke la succession d’opérations conduisant au tracé. Par exemple, un dessin peut être mémorisé par l’ordinateur comme « une droite tracée entre les points (x1, y1) et (x2, y2) », puis « un cercle tracé de centre (x3, y3) et de rayon 30 de couleur rouge ». C’est le processeur qui sera chargé de traduire ces formes en informations interprétables par la carte graphique. L’avantage de ce type d’image est la possibilité de l’agrandir indéfiniment sans perdre la qualité

initiale, ainsi qu’un faible encombrement. L’usage de prédilection des images vectorielles concerne les schémas générés avec certains logiciels de DAO (Dessin Assisté par Ordinateur) comme AutoCAD. Ce type d’image est aussi utilisé

pour les animations Flash. Étant donné que les moyens de visualisation d’images actuels comme les moniteurs d’ordinateur reposent essentiellement sur des images matricielles, les descriptions vectorielles (Fichiers) doivent préalablement être converties en descriptions matricielles avant d’être affichées comme images.
Quelques formats d’images vectorielles : ai (Adobe Illustrator), eps (encapsulated postscript), pdf (portable document format), svg (scalable vector graphics), swf (flash).

imagevectiorielle

Image vectorielle

  1. Courbe tonale:

 

Retoucher une image revient à modifier les valeurs de certains pixels. On peut le faire localement (à un endroit bien précis de l’image) ou globalement. Dans ce dernier cas, on utilise un outil appelé « courbe tonale », qui ressemble au

dessin ci-dessous. Sur l’abscisse, on lit les valeurs originales des pixels et sur l’ordonnée les valeurs après modifications. Sur le graphique ci-contre, tous les pixels de valeurs 100 prendront la valeur 200. Ils vont donc s’éclaircir. La diagonale grise est la courbe où il n’y a aucune modification. En fait, il y a trois courbes tonales : une pour le rouge, une pour le vert et une pour le bleu. On les modifie souvent simultanément de la même façon, mais on peut aussi les modifier séparément.

courbe-tonale1

Changer la luminosité :

 Pour augmenter la luminosité, il suffit d’ajouter une valeur fixe à tous les niveaux.

coube-tonale2

Pour une valeur de + 96, tous les points de l’espace V’ seront blancs.

Merci à Johanne d’accepter de prêter son image à ce cours en remplaçant la traditionnelle Lena

  • Première conséquence : les points les plus noirs auront une valeur égale à 96 et il n’existera plus aucun point entre 0 et 96.
  • Deuxième conséquence : les points ayant une valeur supérieure à 160 deviendront des points parfaitement blancs, puisque la valeur maximale possible est 255. Il y a donc perte d’informations.

coube-tonale3

Pour éviter ces pertes d’informations, il faut que la courbe tonale rejoigne les axes tangentiellement, comme dans l’exemple ci-dessous. Ainsi, aucun point de débordera des valeurs limites minimale (0) ou maximale (255). Il sera en particulier possible de revenir en arrière.

Pour diminuer la luminosité il faudra au contraire soustraire une valeur fixe à tous les niveaux.

coube-tonale4

Pour une valeur de -100, tous les points de l’espace V » seront noirs.

 

  • Première conséquence : les points les plus blancs auront une valeur égale à 156 et il n’existera plus aucun point entre 156 et 255.
  • Deuxième conséquence : les points ayant une valeur comprise entre 0 et 100 deviendront noirs, puisque la valeur minimale est 0. Il y aura donc là aussi perte d’informations.

Augmenter le contraste :

 Pour rendre une image plus contrastée, il faut assombrir les points foncés et éclaircir les points

clairs, par exemple comme dans la figure ci-dessous :

coube-tonale5

Les points de l’espace V  » seront noirs et ceux de l’espace V ‘ blancs.

Pour les mêmes raisons que précédemment, cette manière de faire va causer des pertes d’informations. Aussi faut-il adoucir la courbe :

coube-tonale6

Exercice :

  1. Dessinez une courbe tonale qui va diminuer le contraste.
  2. Dessinez une courbe tonale qui transformera une image couleur en une image composée de pixels noirs et de pixels blancs uniquement.
  1. Quelques traitements classiques

4.1. Négatif

Obtenir le négatif d’une image est très simple : toutes les composantes x de tous les pixels de l’image sont remplacées par 255-x.

4.2. Rouge

Chaque pixel de l’image est une combinaison de rouge, de vert et de bleu. En assignant la valeur 0 aux composantes verte et bleue, on obtient l’image de droite.

4.3. Niveaux de gris

Dans une image en niveaux de gris, chaque pixel est noir, blanc, ou à un niveau de gris entre les deux. Cela signifie que les trois composantes ont la même valeur. L’œil est plus sensible à certaines couleurs qu’à d’autres. Le vert (pur), par exemple, paraît plus clair que le bleu (pur). Pour tenir compte de cette sensibilité dans la transformation d’une image couleur en une image en niveaux de gris, on ne prend généralement pas la moyenne arithmétique des intensités de couleurs fondamentales, mais une moyenne pondérée. La formule standard donnant le niveau de gris en fonction des trois composantes est :  gris = int(round(0.299·rouge + 0.587·vert + 0.114·bleu))

4.4. Seuillage

 Le seuillage d’image est la méthode la plus simple de segmentation d’image. À partir d’une image en niveau de gris, le seuillage d’image peut être utilisé pour créer une image comportant uniquement deux valeurs, noir ou blanc (monochrome). On remplace un à un les pixels d’une image par rapport à une valeur seuil fixée (par exemple 123). Ainsi, si un pixel à une valeur supérieure au seuil (par exemple 150), il prendra la valeur 255 (blanc), et si sa valeur est inférieure (par exemple 100), il prendra la valeur 0 (noir). Avec une image en couleur, on fera de même avec les trois composantes rouge, vert et bleu. Il y aura ainsi huit couleurs possibles pour chaque pixel : blanc, noir, rouge, vert, bleu, magenta, jaune et cyan.

4.5. Sépia

En photographie, le sépia est une qualité de tirage qui ressemble au noir et blanc, mais avec des variations de brun, et non de gris. La couleur sépia dans le système RVB est S(94, 38, 18). Dans la transformation d’une image couleur en une image en nuances de sépia, on tient compte d’un seuil (0 < seuil < 255), qui sépare le sépia assombri et le sépia éclairci. La transformation se fait alors pixel par pixel en deux temps. Pour chaque pixel, on calcule d’abord un niveau de gris qui est la moyenne m des intensités de rouge, vert et bleu. Puis, si le gris obtenu est foncé (m < seuil), on le remplace par une couleur du segment NS, couleur d’autant plus proche du noir que m est petit. Si le gris est plus clair (m > seuil), il est remplacé par une couleur du segment SB, couleur d’autant plus proche du blanc B que m est grand.

cubesepia.png

4.6. Pixellisation

L’image est divisée en rectangles de la taille spécifiée (dans notre exemple 10×10 pixels). Chaque rectangle est ensuite rempli avec la couleur moyenne de la zone.

  1. Filtrage

Le principe du filtrage est de modifier la valeur des pixels d’une image, généralement dans le but d’améliorer son aspect. En pratique, il s’agit de créer une nouvelle image en se servant des valeurs des pixels de l’image d’origine.

Un filtre est une transformation mathématique (appelée produit de convolution) permettant de modifier la valeur d’un pixel en fonction des valeurs des pixels avoisinants, affectées de coefficients.

Les calculs sont faits pour chacune des trois composantes de couleur. Le filtre est représenté par un tableau (une matrice), caractérisé par ses dimensions et ses coefficients, dont le centre correspond au pixel concerné. La somme des coefficients doit faire 1.

5.1. Matrice de convolution

Qu’est-ce que c’est qu’une matrice de convolution? On peut s’en faire une idée approximative sans utiliser les outils mathématiques que bien peu connaissent. Une convolution est un traitement d’une matrice par une autre appelée matrice de convolution ou « noyau  » (kernel).

Notre filtre « Matrice de convolution » utilise une première matrice qui est l’image, c.-à-d une collection de pixels en coordonnées rectangulaires 2D (il y a des matrices 3D…), et un noyau variable selon l’effet souhaité.

GIMP utilise des matrices de convolution 5×5 ou 3×3. Nous nous limiterons aux matrices 3×3, les plus utilisées. Elles suffisent à tous les effets recherchés. Si toutes les cases des bords du noyau sont à 0, le système considère qu’il s’agit d’une matrice 3×3.

Le filtre étudie successivement chacun des pixels de l’image. Pour chaque pixel, que nous appellerons « pixel initial », il multiplie la valeur de ce pixel et de chacun des 8 pixels qui l’entourent par la valeur correspondante dans le noyau. Il additionne l’ensemble des résultats et le pixel initial prend alors la valeur du résultat final.

Vite un exemple, simple :

convolution1

À gauche se trouve la matrice de l’image: chaque pixel est indiqué par sa valeur. Le pixel initial est encadré de rouge. La zone d’action du noyau est encadrée de vert. Au centre, se trouve le noyau et, à droite, le résultat de la convolution.

Voici ce qui s’est passé: le filtre a lu successivement, de gauche à droite et de haut en bas, les pixels de la zone d’action du noyau et il a multiplié chacun d’eux par la valeur correspondante du noyau et additionné les résultats. Le pixel initial a pris la valeur 42 : (40*0)+(42*1)+(46*0) + (46*0)+(50*0)+(55*0) + (52*0)+(56*0)+(58*0) = 42 (le filtre dépose ses résultats sur une copie de l’image et pas directement dans l’image). Le résultat graphique est un décalage du pixel initial d’un pixel vers le bas.

Afficher l'image d'origine

Téléchargez GIMP

Ouvrez le filtre : Filtres → Génériques → Matrice de Convolution.
GIMP1.png

Matrice
C’est la matrice 5×5 du noyau que vous voulez créer: vous entrez les valeurs voulues directement dans les cases.
Diviseur
Le résultat du calcul précédent sera divisé par ce diviseur. Vous n’utiliserez guère que 1 qui laisse le résultat inchangé, et 9 ou 25 selon la taille de la matrice utilisée, ce qui donne la moyenne de la valeur des pixels.
Décalage
Cette valeur est ajoutée au résultat de la division. C’est utile si le résultat risque d’être négatif. Le Décalage peut être négatif.

Bordure
Quand le pixel initial est sur un bord, une partie du noyau porte en dehors des limites de l’image. Vous devez décider de ce que doit faire le filtre.
Étendre
Cette partie du noyau n’est pas prise en compte. Des pixels disparaissent. La ligne libérée est remplacée par une extension de la ligne suivante.
Enrouler
Cette partie du noyau étudiera les pixels du bord opposé, ce qui équivaut à faire réapparaître de l’autre côté les pixels qui disparaissent d’un côté.
Rogner
Les pixels situés en bordure ne sont pas modifiés mais sont rognés.

Canaux
Vous pouvez choisir là le ou les canaux sur lesquels agira le filtre.
Normaliser
Quand cette option est cochée, le Diviseur prend la valeur du résultat du calcul de convolution. Si ce résultat est égal à 0 (on ne peut pas diviser par 0), un Décalage de 128 est appliqué. S’il est négatif (on ne peut pas avoir de couleur négative), c’est un décalage de 255 qui est appliqué (ce qui inverse le résultat).
Poids alpha
Si cette option n’est pas cochée, le calcul ne tient pas compte du degré de transparence des couleurs, ce qui peut être cause d’artefacts lors de l’application d’un flou.
Quelques exemples : 

Détection des bordsFlou

 

 

Augmenter le contrasteRepoussage

 

 

5.2. Lissage

 

Le tableau ci-dessous rend l’image plus floue. On dit que c’est un filtre passe-bas. Appliquer ce tableau revient en fait à remplacer la valeur de chaque pixel par la moyenne des 9 pixels formant un carré.

1/91/91/9
1/91/91/9
1/91/91/9

Rappelons que les valeurs des composantes des pixels sont des nombres entiers compris entre 0 et 255. Si les nouvelles valeurs ne sont plus des entiers, il faudra les arrondir.

5.3. Accentuation

 

À l’inverse, la tableau ci-après rendra l’image plus nette. C’est un filtre passe-haut. Il peut arriver que la nouvelle valeur ne soit plus comprise entre 0 et 255. Il faudra donc toujours prendre min(x, 255) et max(x, 0), où x est la nouvelle valeur.

0-0.50
-0.53-0.5
0-0.50

5.4. Gradient (filtre de Sobel)

 

Pour faire simple, l’opérateur calcule le gradient de l’intensité de chaque pixel. Ceci indique la direction de la plus forte variation du clair au sombre, ainsi que le taux de changement dans cette direction. On connaît alors les points de changement soudain de luminosité, correspondant probablement à des bords.

-101
-202
-101

5.5. Le filtre médian

 

La technique de filtre médian est largement utilisé en traitement d’images numériques, car il permet de réduire le bruit tout en conservant les contours de l’image. L’idée principale du filtre médian est de remplacer chaque pixel par la valeur médiane de son voisinage.

Considérons neuf pixels en niveaux de gris, dont une valeur est aberrante (ici 255) :

2412
22553
793

Le filtre médian va d’abord trier ces valeurs par ordre croissant :  2, 2, 3, 3, 4, 7, 9, 12, 255 et prendre la valeur médiane (la cinquième valeur), ici la valeur 4. La sortie du filtre donnera :

2412
-243
793

Mini-projet : « Mini-photoshop »

 

Réaliser en Python un logiciel en mesure d’effectuer quelques manipulations simples d’images.

  1. Stéganographie

 

Contrairement à la cryptographie, qui chiffre des messages de manière à les rendre incompréhensibles, la stéganographie cache les messages dans un support, par exemple des images ou un texte qui semble anodin.

On peut cacher un texte dans une image numérique et cela de manière parfaitement invisible à l’œil nu. Cette technique s’appelle le tatouage (watermarking en anglais). Elle est utilisée notamment pour protéger des images par copyright, mais on peut aussi transmettre des messages cachés. Nous proposons ici une méthode simple, mais qui fonctionne seulement avec certains formats d’images.

En effet, beaucoup de formats compressent les données et donc modifient les bits de l’image, ce qui a pour effet de détruire le message caché.

6.1 Description d’une image bitmap

 

Une image bitmap peut être décrite comme un tableau de triplets. Chaque triplet donne la couleur d’un pixel dans le système RVB. On aura, par exemple, pour une image large de 3 pixels et haute de 2 pixels :

{255, 255, 255}{153, 219, 5}{102, 0, 0}
{32, 32, 54}{0, 203, 7}{250, 37, 2}

6.2. Représentation binaire du texte

 

Chaque caractère du texte à cacher sera représenté par son code ASCII étendu, écrit en base 2. Le code ASCII de « A » est 65, ce qui donne en binaire, sur un octet : 01000001. Le texte complet sera donc une suite de 0 et de 1, chaque caractère utilisant 8 bits.

6.3. Intégration du texte dans l’image

 

Si l’on enlève les accolades, on peut imaginer l’image comme une suite de nombres compris entre 0 et 255. Notre technique de camouflage consistera à dire qu’un nombre pair correspond à un 0 du texte et qu’un nombre impair correspond à un 1. Il faudra donc modifier certains pixels de l’image, mais ces altérations seront invisibles à l’œil.

On va procéder ainsi : si le nombre du tableau de l’image a la parité que l’on veut, on le laisse inchangé. Si ce n’est pas le cas, on lui ajoute 1 (on soustraira 1 si la valeur de départ est 255, afin d’éviter les débordements).

Reprenons le tableau donné en exemple ci-dessus et camouflons-y la lettre « A » :

original25525525515321951020
Texte (A)01000001
Modifié25425525415422061021

6.4. Récupération du texte

 

La récupération se fait en cinq étapes :

  1. Récupérer le tableau décrivant l’image.
  2. Remplacer un nombre pair par 0, un nombre impair par 1.
  3. Grouper les bits par groupes de 8.
  4. Convertir chaque octet en nombre décimal.
  5. Écrire les caractères correspondant aux codes ASCII obtenus.

Mini projet  :

 

Programmez en Python cette méthode pour cacher un texte dans une image.