ISN Numérisation

Un livre de Wikilivres.
Aller à : navigation, rechercher

Numérisation des données[modifier | modifier le wikicode]

Savoirs :

L'ordinateur manipule uniquement des valeurs numériques. Une étape de numérisation des objets du monde physique est donc indispensable.

Capacités :
  • Coder un nombre, un caractère au travers d'un code standard, un texte sous forme d'une liste de valeurs numériques.
  • Numériser une image ou un son sous forme d'un tableau de valeurs numériques.
    • Modifier format, taille, contraste ou luminance d'images numériques.
    • Filtrer et détecter des informations spécifiques.
    • Créer une image à l'aide d'un logiciel de modélisation.
Observation :

Il est ici utile de faire référence à des notions technologiques introduites à propos des architectures matérielles. Les images et les sons sont choisis comme contexte applicatif et sont manipulés via des logiciels de traitement ou de synthèse. Le traitement numérique de la lumière et du son est en lien avec les principes physiques sous-jacents, qu'il est utile d'évoquer au moment voulu.

Signal analogique, signal numérique[modifier | modifier le wikicode]

Un signal analogique se présente souvent sous forme d'une tension électrique qui varie avec le temps. On dit que le signal est analogique quand n'importe quelle valeur de la tension électrique a de la signification. Un signal numérique est aussi une tension qui varie avec le temps, mais seules quelques valeurs de tension ont une signification précise.

Numérisation d'un signal[modifier | modifier le wikicode]

Un convertisseur analogique numérique (CAN) reçoit en entrée un signal analogique (par exemple,le signal électrique venu d'un microphone,qui représente les variations de la pression acoustique), et un signal d'horloge. À chaque top de l'horloge, le convertisseur CAN doit présenter sur son bus de sortie une valeur binaire qui représente au mieux le signal analogique d'entrée.

Pour obtenir une numérisation de haute qualité, il faut :

  • un signal d'horloge assez rapide : le nombre de tops d'horloge à chaque seconde s'appelle la fréquence d'échantillonnage ; elle doit être plus rapide que les variations typiques du signal analogique à numériser.
  • une résolution suffisante pour les données en sortie : si le bus de sortie possède bits, alors il peut représenter valeurs numériques différentes.

Un exemple de numérisation[modifier | modifier le wikicode]

width=5cm width=5cm width=5cm
Graphique d'un signal analogique Numérisation du signal Graphique d'un signal numérique

Dans les exemples présentés ci-dessus, la numérisation du signal analogique a été réalisée en distinguant 32 valeurs différentes (et 32 seulement : codage possible sur 5 bits) dans l'intervalle compris entre -1 V et +1 V. Un millier d'échantillons de du signal analogique ont été évalués pour effectuer la numérisation.

Exercice : analogique/numérique[modifier | modifier le wikicode]

  • À quoi ressemblerait le signal numérique si celui-ci était codé sur 2 bits, c'est à dire que 4 valeurs différentes seulement du signal peuvent exister ?
  • Supposons que le signal numérique ait une forte résolution (par exemple 10 bits, ce qui permet 1024 valeurs significatives distinctes), mais que les échantillons soient peu nombreux. À quoi ressemblerait le signal numérisé s'il n' avait que deux échantillons numérisés pendant la durée représentée sur le graphique ?... et s'il n'y avait qu'un seul échantillon ?

Images numériques[modifier | modifier le wikicode]

Les appareils photo et les caméras les plus utilisés maintenant fonctionnent avec des capteurs CCD, qui sont des matrices formées de petits rectangles sensibles à la lumière. L'électronique associé au capteur CCD échantillonne sur commande les valeur des charges électriques apparues sur chaque petit rectangle, qui dépend de la lumière reçue. La valeur de chacune de ces charges électriques est numérisée, et un tableau de valeurs numériques est enregistré dans une mémoire.

Les appareils de bonne qualité utilisent de grandes quantités de mémoire, quand les images et les vidéos sont conservées sans chercher à comprimer les données (formats de type "RAW"). De nombreux appareils grand public compriment systématiquement les données afin de pouvoir en emmagasiner plus dans la même mémoire.

Comparaison entre formats de fichiers pour des images[modifier | modifier le wikicode]

Format de fichier BMP XPM PNG (couleurs indexées) JPG
principales caractéristiques non comprimé, 32 bits par pixel non comprimé, indexé, fichier texte lisible comprimé, sans perte comprimé, avec des pertes
Taille en kilo-octets 16,5 4,5 0,6 2,5

L'image choisie pour le tableau ci-dessus mesure pixels, elle comporte 4096 pixels indépendants. On peut remarquer que les tailles de certains fichiers non-comprimés sont prévisibles :

  • format BMP : Présence d'un en-tête, plus 4 octets par pixels : , pour un total de 16,6 kO.
  • format XPM : présence d'un en-tête, plus un octet par pixel : , pour un total de 4,5 kO.

Les systèmes de compression ont des efficacités variables selon le type d'image à encoder. Comme l'image choisie a un nombre limité de couleurs (huit) la compression PNG réussit très bien : le fichier pèse moins d'un kilo-octet. Le fichier JPG pèse plus du double. Observez bien les pixels de ce dernier fichier : on distingue des altérations.

Les composantes R, V, B d'une image en couleur[modifier | modifier le wikicode]

Les écran et les vidéoprojecteurs connectés aux ordinateurs utilisent la synthèse additive pour créer les palettes de couleurs qui nous sont présentées.

En synthèse additive, les couleurs primaires sont rouge, vert, bleu (RVB en français, RGB en anglais).

Ci dessous, voici une table de synthèse additive pour les couleurs primaires. Les notations rgb(x,y,z) sont des triplets de valeurs permettant de donner la composition d'une lumière. Les valeurs de x, y et z sont dans un intervalle de 0 (le minimum) à 255 (le maximum). Le couleurs primaires correspondent aux notation suivantes :

  • R rgb(255,0,0)
  • V rgb(0,255,0)
  • B rgb(0,0,255)
R V B
R J rgb(255,255,0) M rgb(255,0,255)
V J rgb(255,255,0) C rgb(0,255,255)
B M rgb(255,0,255) C rgb(0,255,255)

Le couleurs J, M, C sont respectivement le jaune, le magenta et le cyan. Le noir (N rgb(0,0,0)) est l'absence de lumière (ni R, ni V, ni B), le blanc (Bl rgb(255,255,255)) s'obtient en additionnant R, V et B.

Transformer une image par calcul[modifier | modifier le wikicode]

On peut représenter les images dans un ordinateur par un tableau rectangulaire de nombres représentant chacun un pixel de l'image. Il est quelque fois commode de considérer trois tableaux de même dimension, pour les trois composantes RVB de l'image.

Des calculs appliqués aux cases du tableau rectangulaire qui représente une image permettent de créer des images nouvelles aux propriétés intéressantes.

On peut par exemple remplacer le chiffre dans chaque case par une moyenne (avec coefficients) des chiffres de cases voisines. En choisissant bien les coefficients, on peut obtenir des opérations nommées « filtres », pour simuler un flou, un flou cinétique, pour accentuer les détails, ou pour extraire les bords d'objets contrastés.

Un exemple d'algorithme[modifier | modifier le wikicode]

debut
  {les données de l'images sont dans la table t}
  largeur, hauteur := taille(t)
  t1 := nouvelle table(hauteur,largeur)
  pour y dans intervalle(0,hauteur)
    pour x dans intervalle(0,largeur)
      t1[y,x] := traitement (t, y, x)
    fin pour
  fin pour
  resultat := t1
fin

Les données de l'image de départ se présentent sous forme d'une table t, organisée en hauteur lignes et largeur colonnes.

Une nouvelle table t1 de même dimension est créée pour contenir la nouvelle image.

Deux boucles indicées par les variables x et y permettent de parcourir chaque pixel de la table t1, qui résulte d'un calcul basé sur les valeurs contenues dans la table t et les coordonnées (x,y). Le calcul est réalisé par la fonction nommée traitement.

Les implémentations ci-dessous utilisent une petite table nommée « filtre » contenant un jeu de coefficients. Une moyenne est faite des valeurs de pixels de la table t, en utilisant les coefficients du filtre. Cette méthode permet entre autres de flouter l'image de départ.

Exemple en Python[modifier | modifier le wikicode]

  1 #!/usr/bin/python
  2 # -*- coding: utf-8 -*-
  3 
  4 import Image
  5 
  6 ##########################################################
  7 #   un filtre pour obtenir un peu de flou "gaussien"     #
  8 ##########################################################
  9 fFlou=[
 10     [0.5,0.7,0.5],
 11     [0.7,1.0,0.5],
 12     [0.5,0.7,0.5],
 13     ]
 14 
 15 #############################################################
 16 #   un filtre pour mettre en valeur les zones contrastées   #
 17 #############################################################
 18 fContraste=[
 19     [-0.05,-0.2,-0.05],
 20     [-0.2,1.01,-0.2],
 21     [-0.05,-0.2,-0.05],
 22     ]
 23 
 24 ##########################################################
 25 #   implémentation de l'algorithme suggéré plus haut     #
 26 ##########################################################
 27 def appliqueFiltre(t,f):
 28     """
 29     Applique un filtre sur un tableau d'image.
 30     Les valeurs du filtre sont des coefficients utilisées pour faire des
 31     moyennes pondérées entre pixels voisins
 32     @param t tableau encodant une image en gris
 33     @param f un filtre (tableau plus petit)
 34     @return un tableau de la même taille que t, après passage du filtre
 35     """
 36     h=len(t)     #hauteur de t
 37     w=len(t[0])  #largeur de t
 38 
 39     result=[]
 40     for y in range(h):
 41         line=[]
 42         for x in range(w):
 43             line.append(traitement(t, y, x, f))
 44         result.append(line)
 45     return result
 46 
 47 ##########################################################
 48 #   implémentation de la fonction "traitement"           #
 49 ##########################################################
 50 def traitement(t, y, x, f):
 51     """
 52     calcule la valeur d'un pixel nouveau en utilisant une image originale
 53     et un jeu de coordonnées. Une table de coefficients est utilisée.
 54     @param t la table del'image originale
 55     @param y désigne une ligne dans l'image
 56     @param x désigne une colonne dans l'image
 57     @param f une table de coefficients(un filtre)
 58     @return une valeur utilisable pour créer un nouveau pixel
 59     """
 60     h=len(f)     #hauteur de f
 61     w=len(f[0])  #largeur de f
 62     ifx=range(-w/2,(w+1)/2) # intervalle de même largeur que f centré sur 0
 63     ify=range(-h/2,(h+1)/2) # intervalle de même hauteur que f centré sur 0
 64     dfx=w/2 # décalage horizontal de f
 65     dfy=h/2 # décalage vertical de f
 66 
 67     h=len(t)     #hauteur de t
 68     w=len(t[0])  #largeur de t
 69     s=0
 70     n=0
 71     for iy in ify:
 72         for ix in ifx:
 73             jx=ix+x # coordonnées à prendre encompte dans
 74             jy=iy+y # le tableau de départ t
 75             kx=ix+dfx # coordonnées dans le filtre
 76             ky=iy+dfy # nécessairement positives ou nulles
 77             if jx in range(w) and jy in range(h):
 78                 # si les coordonnées sont dans le tableau t
 79                 coef=f[ky][kx]
 80                 n+=coef
 81                 s+=t[jy][jx]*coef
 82     return s/n
 83 
 84 ##########################################################
 85 #   quelques fonctions utilitaires ci-dessous, pour      #
 86 #   fabriquer des tables explicites à partir d'images    #
 87 #   en utilisant le module python Image.                 #
 88 ##########################################################
 89 def troisCanaux(filename):
 90     """
 91     Ouvre un fichier image et extrait troix canaux de couleur de l'image
 92     du fichier
 93     @param filename le nom du fichier à ouvrir
 94     @result un triplet d'images en niveau de gris pour rouge, vert et bleu
 95     """
 96     im=Image.open(filename)
 97     im=im.convert("RGB")
 98     return im.split()
 99 
100 def canalVersTable(canal):
101     """
102     récupère lesdonnées d'un canal de type L (valeurs de gris)
103     dans un tableau
104     @param canal un canal de gris
105     @return un tableau avec les valeurs organisées dedans
106     """
107     w,h=canal.size
108     result=[]
109     for y in range(h):
110         line=[]
111         for x in range(w):
112             line.append(canal.getpixel((x,y)))
113         result.append(line)
114     return result
115 
116 def tableVersCanal(t):
117     """
118     convertit une table rectangulaire de nombres
119     vers un canal de valeurs de gris d'image
120     """
121     h=len(t)
122     w=len(t[0])
123     result=Image.new("L",(w,h))
124     for y in range(h):
125         for x in range(w):
126             result.putpixel((x,y),t[y][x])
127     return result
128 
129 
130 
131 ########################################################
132 #  programme à effectuer quand ce fichier est invoqué  #
133 #  directement. On peut invoquer ce fichier suivi du   #
134 #  nom d'un fichier d'image, ou donner le nom d'un     #
135 #  fichier d'image interactivement pendant que ce      #
136 #  programme fonctionne.                               #
137 ########################################################
138 import sys, os.path
139 if __name__ == "__main__":
140     if len(sys.argv)>1:
141         nomFichier=sys.argv[1]
142     else:
143         nomFichier=raw_input("Tapez le nom d'un fichier d'image")
144     r, v, b = troisCanaux(nomFichier)
145     t=canalVersTable(r)
146     t1=appliqueFiltre(t,fFlou)
147     r1=tableVersCanal(t1)
148     r.show()
149     raw_input("Voici le canal R de %s. Appuyez sur Entrée" %nomFichier)
150     r1.show()
151     raw_input("Voici l'image obtenue après application du filtre de flou. Appuyez sur Entrée")
152     t2=appliqueFiltre(t,fContraste)
153     r2=tableVersCanal(t2)
154     r2.show()
155     raw_input("Voici l'image obtenue après le filtre d'accentuation. Appuyez sur Entrée")
156     t3=appliqueFiltre(t1,fContraste)
157     r3=tableVersCanal(t3)
158     r3.show()
159     raw_input("Enfin, on applique le filtre de flou après l'autre. Appuyez sur Entrée")
160 
161     # enregistre les nouvelles images.
162     path, ext = os.path.splitext(nomFichier)
163     nf="%s%d%s" %(path, 0, ext)
164     r.save(nf)
165     print "fichier sauvé :", nf
166     nf="%s%d%s" %(path, 1, ext)
167     r1.save(nf)
168     print "fichier sauvé :", nf
169     nf="%s%d%s" %(path, 2, ext)
170     r2.save(nf)
171     print "fichier sauvé :", nf
172     nf="%s%d%s" %(path, 3, ext)
173     r3.save(nf)
174     print "fichier sauvé :", nf
Exécution du programme[modifier | modifier le wikicode]

Voici une trace de l'exécution de ce programme dans une console :

$ ./filtreImages.py logo.png 
Voici le canal R de logo.png. Appuyez sur Entrée
Voici l'image obtenue après application du filtre de flou. Appuyez sur Entrée
Voici l'image obtenue après le filtre d'accentuation. Appuyez sur Entrée
Enfin, on applique le filtre de flou après l'autre. Appuyez sur Entrée
fichier sauvé : logo0.png
fichier sauvé : logo1.png
fichier sauvé : logo2.png
fichier sauvé : logo3.png

L'image d'origine est celle- ci : Pidgin-logo-orig.png

Voici les images affichées :

  • le canal R de l'image : Pidgin-logo0.png
  • le canal R de l'image après application du filtre de flou : Pidgin-logo1.png
  • le canal R de l'image après application du filtre d'accentuation : Pidgin-logo2.png
  • le canal R de l'image après application des deux filtres : Pidgin-logo3.png

Exemple en Javascript[modifier | modifier le wikicode]

Utilisation d'un logiciel de traitement d'image[modifier | modifier le wikicode]