Numérique et sciences informatiques

Des tableaux et des images

Une image c'est quoi ?

Nous travaillerons dans un premier temps avec cette image

Une fois téléchargée, un clic droit dessus pour accéder aux propriétés.

Il est indiquée que ses dimensions sont de pixels.

pixel : De l'anglais pixel, mot forgé (1969) à partir de pix (variante de pics, pluriel de pic, abréviation de picture « image ») et de el(ement) (« élément »), littéralement « élément d'image ».

Cela signifie que cette image est constituée de pixels qui contiennent chacun une couleur.

Une couleur étant une combinaison des trois couleurs fondamentales : le rouge, le vert et le bleu.

On considère donc qu'une image est un tableau de pixels qui contiennent des couleurs.

SimulationFaire afficher une image

Dans Processing en mode Python, il suffit de glisser-déposer l'image dans le sketch ( celle-ci sera automatiquement mise dans un dossier 'data')

Glissez-déposez l'image de la Joconde dans le sketch.

vérifiez dans l'onglet "sketch" / "Afficher le dossier" que l'image s'y trouve bien..

On crée une fenêtre d'affichage aux dimensions de cette image, on charge l'image dans une variable, puis on l'affiche

1
size(408,320)
2
img=loadImage("data/joconde.png")
3
image(img,0,0)

L'instruction : image(img,0,0) signifie : afficher l'image se trouvant dans ' img' aux coordonnées (0,0) ( il s'agit du coin supérieur gauche de l'image que l'on place aux coordonnées (0,0))

On peut modifier la taille de l'image à l'affichage : en complétant l'instruction : image(img,0,0,largeur, hauteur) 

Testez ce programme :

1
size(408,320)
2
img=loadImage("data/joconde.png")
3
image(img,0,0,102,80)
4
image(img,102,0,102,80)

Accès aux pixels d'une image

Lorsque l'on charge une image, les pixels sont automatiquement enregistrés dans une liste.

Prenons l'exemple d'une image de pixels :

  • Chaque pixel se repère par ses coordonnées (x , y) dans le tableau

  • Chaque pixel possède un on l’appellera l'index 

Par exemple : le pixel d'index 65 à pour coordonnées ( 5 ; 6)

Notez bien que : La 1ère ligne est la ligne 0 et la 1ère colonne est la colonne 0

Lors du chargement de l'image ce tableau est enregistré en liste...

Enregistrement en liste.

Comment obtenir l'index d'un pixel à partir de ses coordonnées ?

Par exemple : la case de coordonnées (5,6) donne l'index 65.

La formule permettant de passer des coordonnées à l'index est : (abscisse) +(ordonnée *largeur de l'image)

65=5+6*10

Dans une image de pixels, le pixel de coordonnées ( 80, 150) se trouve à l'index 80+150*400=60080 de la liste

Le programme ci-dessous affiche les composantes (r,g,b) du pixel de coordonnées ( 80 ; 150) de l'image de la Joconde et une petite ellipse pour le localiser sur l'image

1
size(408,320)#taille de la fenêtre
2
img=loadImage("data/joconde.png")#chargement de l'image
3
image(img,0,0)#affichage de l'image
4
index=80+150*408# calcul de l'index
5
r=red(img.pixels[index])#composante rouge du pixel
6
g=green(img.pixels[index])
7
b=blue(img.pixels[index])
8
noFill()#pas de remplissage
9
stroke(255,255,255)#bord blanc
10
ellipse(80,150,5,5)#ellipse
11
print(r,g,b)#affichage dans la console de la couleur(r,g,b)

Lecture de l'instruction : r=red(img.pixels[index])

Mettre dans la variable 'r' la composante rouge(red) du pixel de l'image se trouvant dans la variable 'img' à l'index (80+150*408)

  • Faites afficher la couleur du pixel de coordonnées ( 200 ; 400)

SimulationModification des pixels d'une image

Dans cet exemple nous allons modifier tous les pixels rouge de l'image, (on les mets tous à 255)

On va également délocaliser le calcul de l'index dans une fonction.

On va également créer une image vide, que l'on remplira avec les pixels modifiés de l'image de la Joconde.

On affichera les deux images.

1
2
def calculindex(x,y):#le calcul de l'index
3
    return x+y*408
4
5
def setup():
6
    size(408,320)# taille de la fenêtre
7
    img=loadImage("data/joconde.png")#chargement de l'image
8
    img2=createImage(408,320,RGB)# création d'une image vide
9
    for x in range(0,408,1):# pour tous les pixels de l'image
10
        for y in range(0,320,1):
11
            index=calculindex(x,y)# calcul de l'index
12
            r=red(img.pixels[index])#composante rouge du pixel de l'image
13
            g=green(img.pixels[index])
14
            b=blue(img.pixels[index])
15
            img2.pixels[index]=color(255,g,b)# remplissage de l'image vide
16
    image(img2,0,0)# affichage des images
17
    image(img,0,0,102,80)
  • Faites de même avec les pixels vert

  • Et les bleus

DéfinitionModification par convolution

Modifier une image par convolution consiste à remplacer les composantes de chaque pixel par une combinaison des valeurs des composantes des pixels voisins et de lui-même .

On ne prendra en compte que les pixels qui ont 8 voisins :

Un pixel et ses 8 voisins, et leurs coordonnées.

Par exemple : On va  appliquer la modification suivante : (filtre passe haut)

Avec :

Soit :

Voici le programme :

1
#fonction qui renvoie l'index
2
def calculindex(x,y):
3
    return x+y*408
4
5
def setup():
6
    size(408,320)
7
    img=loadImage("data/joconde.png")#chargement de l'image
8
    img2=createImage(408,320,RGB)#création d'une image vide
9
    for x in range(1,407,1):# pour tous les pixels (sauf ceux des bords qui n'ont pas 8 voisins)
10
        for y in range(1,319,1):
11
            index1=calculindex(x-1,y-1)#calculs des index
12
            index2=calculindex(x,y-1)
13
            index3=calculindex(x+1,y-1)
14
            index4=calculindex(x-1,y)
15
            index5=calculindex(x,y)
16
            index6=calculindex(x+1,y)
17
            index7=calculindex(x-1,y+1)
18
            index8=calculindex(x,y+1)
19
            index9=calculindex(x+1,y+1)
20
            #modification des pixels
21
            r=-red(img.pixels[index2])-red(img.pixels[index4])+5*red(img.pixels[index5])-red(img.pixels[index6])-red(img.pixels[index8])
22
            g=-green(img.pixels[index2])-green(img.pixels[index4])+5*green(img.pixels[index5])-green(img.pixels[index6])-green(img.pixels[index8])
23
            b=-blue(img.pixels[index2])-blue(img.pixels[index4])+5*blue(img.pixels[index5])-blue(img.pixels[index6])-blue(img.pixels[index8])
24
            img2.pixels[index5]=color(r,g,b)#remplissage de l'image vide
25
    image(img2,0,0)#affichage des images
26
    image(img,0,0,102,80)      

Ce programme, bien que fonctionnel, ne permet pas sans de longues transformations de modifier le type de convolution que l'on souhaite faire.

Il serait intéressant de 'délocaliser' la modification des pixels dans une fonction.

SimulationAmélioration du programme

La structure du programme est :

1
# déclaration de la matrice de convolution(tableau 3x3)
2
matrice=[[0,-1,0],
3
         [-1,5,-1],
4
         [0,-1,0]]
5
6
def convolution(x, y, matrice, img):  # fonction à écrire
7
    
8
9
10
#fonction qui renvoie l'index
11
def calculindex(x,y):
12
    return x+y*408
13
14
def setup():
15
    size(408,320)
16
    global img,img2,matrice
17
    img=loadImage("data/joconde.png")#chargement de l'image
18
    img2=createImage(408,320,RGB)#création d'une image vide
19
    for x in range(1,407,1):# pour tous les pixels (sauf ceux des bords qui n'ont pas 8 voisins)
20
        for y in range(1,319,1):
21
            index=calculindex(x,y)
22
            #modification des pixels
23
            c=convolution(x,y,matrice,img)# c recevra le résultat de la fonction
24
            img2.pixels[index]=c#remplissage de l'image vide
25
    image(img2,0,0)#affichage des images
26
    image(img,0,0,102,80)      

Que doit faire cette fonction ?

Cette fonction doit renvoyer une couleur ( return color(r,v,b) )

Pour la composante rouge du pixel, il faudra calculer cette somme 

En observant cette somme, on remarque que chaque terme peut se résumer à :

Pour i et j valant -1 puis 0 et 1

rouge(x+i,y+j)*matrice[i+1][j+1]

le pseudo code de calcul (pour le rouge )de cette fonction est :

1
rougetotal=0.0
2
pour i variant de -1 à 1 par pas de 1:
3
    pour j variant de -1 à 1 par pas de 1:
4
        index <-- calculindex(x+i,y+j)
5
        rougetotal <-- rougetotal+red(img.pixels[index])*matrice[i+1][j+1]
  • Finalisez cette fonction

  • Faites des essais avec d'autres matrices (cherchez sur le web)

Suivant les calculs faits, il se peut que le résultat ne soit pas compris entre 0 et 255.

On peut, avec l'instruction : rougetotal = constrain(rougetotal,0,255) , contraindre le résultat à être dans la plage (0,255)

Corrigé :

1
matrice=[[0,-1,0],
2
         [-1,5,-1],
3
         [0,-1,0]]
4
5
def convolution(x, y, matrice, img):  # fonction
6
    rtotal = 0.0
7
    gtotal = 0.0
8
    btotal = 0.0
9
    for i in range(-1,2,1):# i vaut -1 , 0 puis 1
10
        for j in range(-1,2,1):# et pour chaque i , j vaut à son tour -1 , 0 puis 1
11
            index=calculindex(x+i,y+j)#localisation des voisins
12
            #calculs
13
            rtotal=rtotal+red(img.pixels[index])*matrice[i+1][j+1] # on ajoute le coefficient modifié
14
            gtotal=gtotal+green(img.pixels[index])*matrice[i+1][j+1]
15
            btotal=btotal+blue(img.pixels[index])*matrice[i+1][j+1]
16
    rtotal = constrain(rtotal,0,255)# on contraint les valeurs à être entre 0 et 255
17
    gtotal = constrain(gtotal,0,255)
18
    btotal = constrain(btotal,0,255)
19
    return color(rtotal,gtotal,btotal) # on renvoie une couleur
20
21
#fonction qui renvoie l'index
22
def calculindex(x,y):
23
    return x+y*408
24
25
def setup():
26
    size(408,320)
27
    global img,img2,matrice
28
    img=loadImage("data/joconde.png")#chargement de l'image
29
    img2=createImage(408,320,RGB)#création d'une image vide
30
    for x in range(1,407,1):# pour tous les pixels (sauf ceux des bords qui n'ont pas 8 voisins)
31
        for y in range(1,319,1):
32
            index=calculindex(x,y)
33
            #modification des pixels
34
            c=convolution(x,y,matrice,img)
35
            img2.pixels[index]=c#remplissage de l'image vide
36
    image(img2,0,0)#affichage des images
37
    image(img,0,0,102,80)      
PrécédentPrécédentSuivantSuivant
AccueilAccueilImprimerImprimer Stéphan Van Zuijlen Licence de documentation libre GNURéalisé avec Scenari (nouvelle fenêtre)