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.
Simulation : Faire 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
size(408,320)
img=loadImage("data/joconde.png")
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 :
size(408,320)
img=loadImage("data/joconde.png")
image(img,0,0,102,80)
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
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...
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
|
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
size(408,320)#taille de la fenêtre
img=loadImage("data/joconde.png")#chargement de l'image
image(img,0,0)#affichage de l'image
index=80+150*408# calcul de l'index
r=red(img.pixels[index])#composante rouge du pixel
g=green(img.pixels[index])
b=blue(img.pixels[index])
noFill()#pas de remplissage
stroke(255,255,255)#bord blanc
ellipse(80,150,5,5)#ellipse
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)
Simulation : Modification 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.
def calculindex(x,y):#le calcul de l'index
return x+y*408
def setup():
size(408,320)# taille de la fenêtre
img=loadImage("data/joconde.png")#chargement de l'image
img2=createImage(408,320,RGB)# création d'une image vide
for x in range(0,408,1):# pour tous les pixels de l'image
for y in range(0,320,1):
index=calculindex(x,y)# calcul de l'index
r=red(img.pixels[index])#composante rouge du pixel de l'image
g=green(img.pixels[index])
b=blue(img.pixels[index])
img2.pixels[index]=color(255,g,b)# remplissage de l'image vide
image(img2,0,0)# affichage des images
image(img,0,0,102,80)
Faites de même avec les pixels vert
Et les bleus
Définition : Modification 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 :
Par exemple : On va appliquer la modification suivante : (filtre passe haut)
Voici le programme :
#fonction qui renvoie l'index
def calculindex(x,y):
return x+y*408
def setup():
size(408,320)
img=loadImage("data/joconde.png")#chargement de l'image
img2=createImage(408,320,RGB)#création d'une image vide
for x in range(1,407,1):# pour tous les pixels (sauf ceux des bords qui n'ont pas 8 voisins)
for y in range(1,319,1):
index1=calculindex(x-1,y-1)#calculs des index
index2=calculindex(x,y-1)
index3=calculindex(x+1,y-1)
index4=calculindex(x-1,y)
index5=calculindex(x,y)
index6=calculindex(x+1,y)
index7=calculindex(x-1,y+1)
index8=calculindex(x,y+1)
index9=calculindex(x+1,y+1)
#modification des pixels
r=-red(img.pixels[index2])-red(img.pixels[index4])+5*red(img.pixels[index5])-red(img.pixels[index6])-red(img.pixels[index8])
g=-green(img.pixels[index2])-green(img.pixels[index4])+5*green(img.pixels[index5])-green(img.pixels[index6])-green(img.pixels[index8])
b=-blue(img.pixels[index2])-blue(img.pixels[index4])+5*blue(img.pixels[index5])-blue(img.pixels[index6])-blue(img.pixels[index8])
img2.pixels[index5]=color(r,g,b)#remplissage de l'image vide
image(img2,0,0)#affichage des images
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.
Simulation : Amélioration du programme
La structure du programme est :
# déclaration de la matrice de convolution(tableau 3x3)
matrice=[[0,-1,0],
[-1,5,-1],
[0,-1,0]]
def convolution(x, y, matrice, img): # fonction à écrire
#fonction qui renvoie l'index
def calculindex(x,y):
return x+y*408
def setup():
size(408,320)
global img,img2,matrice
img=loadImage("data/joconde.png")#chargement de l'image
img2=createImage(408,320,RGB)#création d'une image vide
for x in range(1,407,1):# pour tous les pixels (sauf ceux des bords qui n'ont pas 8 voisins)
for y in range(1,319,1):
index=calculindex(x,y)
#modification des pixels
c=convolution(x,y,matrice,img)# c recevra le résultat de la fonction
img2.pixels[index]=c#remplissage de l'image vide
image(img2,0,0)#affichage des images
image(img,0,0,102,80)
Que doit faire cette fonction ?
Cette fonction doit renvoyer une couleur ( 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 :
rougetotal=0.0
pour i variant de -1 à 1 par pas de 1:
pour j variant de -1 à 1 par pas de 1:
index <-- calculindex(x+i,y+j)
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é :
matrice=[[0,-1,0],
[-1,5,-1],
[0,-1,0]]
def convolution(x, y, matrice, img): # fonction
rtotal = 0.0
gtotal = 0.0
btotal = 0.0
for i in range(-1,2,1):# i vaut -1 , 0 puis 1
for j in range(-1,2,1):# et pour chaque i , j vaut à son tour -1 , 0 puis 1
index=calculindex(x+i,y+j)#localisation des voisins
#calculs
rtotal=rtotal+red(img.pixels[index])*matrice[i+1][j+1] # on ajoute le coefficient modifié
gtotal=gtotal+green(img.pixels[index])*matrice[i+1][j+1]
btotal=btotal+blue(img.pixels[index])*matrice[i+1][j+1]
rtotal = constrain(rtotal,0,255)# on contraint les valeurs à être entre 0 et 255
gtotal = constrain(gtotal,0,255)
btotal = constrain(btotal,0,255)
return color(rtotal,gtotal,btotal) # on renvoie une couleur
#fonction qui renvoie l'index
def calculindex(x,y):
return x+y*408
def setup():
size(408,320)
global img,img2,matrice
img=loadImage("data/joconde.png")#chargement de l'image
img2=createImage(408,320,RGB)#création d'une image vide
for x in range(1,407,1):# pour tous les pixels (sauf ceux des bords qui n'ont pas 8 voisins)
for y in range(1,319,1):
index=calculindex(x,y)
#modification des pixels
c=convolution(x,y,matrice,img)
img2.pixels[index]=c#remplissage de l'image vide
image(img2,0,0)#affichage des images
image(img,0,0,102,80)