La photographie numérique

Les images

Notre espace de travail

On travaille avec Processing en mode Python et/ou avec EduPython

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)
  • Faites en sorte qu'il y ait 16 images de la Joconde affichées dans la fenêtre.

Il faut obtenir ce résultat :

ComplémentFaire afficher une image dans Edupython

Dans EduPython l'affichage d'une image dans une fenêtre, nécessite l'utilisation de bibliothèques ( il y en a plusieurs : Matplotlib, Pygame, Pylab, etc... )

La manipulation d'images se fera avec la bibliothèque 'pillow'

Dans un dossier qui contient notre image de la Joconde enregistrez et exécutez le programme suivant

1
# Créé par vstep, le 31/01/2019 en Python 3.4
2
from PIL import Image
3
from pylab import *
4
5
# chargement de l'image
6
img=Image.open("joconde.png")
7
8
# affichage
9
# non affichage des axes
10
xticks([]), yticks([])
11
title('La joconde')
12
plt.imshow(img)
13
show()
14

Accès aux pixels d'une image (Processing)

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 ( 400 ; 200)

SimulationModification des pixels d'une image (Processing)

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

ComplémentModification des pixels d'une image ( EduPython)

La bibliothèque 'pillow' permet de s'affranchir de la recherche de l'index d'un pixel dans la liste.

Pour atteindre la couleur ( r, v, b) d'un pixel, il suffit d'utiliser la commande :

r,v,b,a=img.getpixel((x,y))

Cette commande stocke dans les variables r,v et b les composantes rouge, verte et bleue du pixel de coordonnées (x, y).

Il y a cependant, une contrainte : les pixels de notre image possède une valeur "a" ( le taux d'opacité de l'image ) également codé de 0 (totalement opaque) à 255 sans opacité.

Dans un dossier qui contient notre image de la Joconde enregistrez et exécutez le programme suivant

1
# Créé par vstep, le 31/01/2019 en Python 3.4
2
from PIL import Image
3
from pylab import *
4
5
# chargement des images
6
img=Image.open("joconde.png")
7
largeur,hauteur=img.size
8
#création d'une image vide
9
img2=Image.new('RGB',(largeur,hauteur))
10
11
#traitement
12
for y in range(hauteur):
13
    for x in range(largeur):
14
        r,v,b,a=img.getpixel((x,y))
15
        img2.putpixel((x,y),(255,v,b))
16
17
18
#affichage, deux images dans la même fenêtre( l'originale et la modifiée)
19
subplot(1,2,1)
20
xticks([]), yticks([])
21
title('La joconde')
22
plt.imshow(img)
23
24
subplot(1,2,2)
25
xticks([]), yticks([])
26
title('La joconde(filtre rouge)')
27
plt.imshow(img2)
28
29
show()
  • Faites de même avec les pixels vert

  • Et les bleus

SimulationMettre une image en niveau de gris (Processing)

Toutes les nuances de gris s'obtiennent par des couleurs de la forme ( c , c , c) c'est à dire que les composantes rouge, verte et bleue ont la même valeur.

Du blanc : (255,255,255) jusqu'au noir (0,0,0).

Pour mettre une image en niveau de gris, il suffit donc de remplacer les composantes (r ,g , b) de chaque pixels par leur moyenne : .

  • Modifiez le programme précédent pour qu'il affiche la Joconde en niveau de gris.

ComplémentMettre une image en niveau de gris (Edupython)

Réalisez le programme dans EduPython

SimulationMettre une image en noir et blanc (Processing)

Pour mettre une image en noir et blanc, il faut partir d'une image en niveau de gris, puis si la valeur calculée est supérieure à un certain seuil ( par exemple 127) alors on la met en blanc (255) sinon on la met en noir (0)

En notant c la moyenne calculée dans le programme précédent, il faudra rajouter dans le programme :

1
if c>127:
2
   c=255
3
else:
4
   c=0

ComplémentMettre une image en noir et blanc (EduPython)

On utilisera le programme du niveau de gris (EduPython) auquel on rajoutera les modifications nécessaires

ComplémentTravail à faire

Réalisez un programme qui transforme chaque pixel de l'image en son complément à 255.

C'est à dire : ( r,v,b) ---> (255-r, 255-v , 255-b )

SimulationFiltrage par seuil (Processing)

Le filtrage par seuil consiste, pour chaque pixel d'une image, d'imposer une valeur à l'une des composantes si celle-ci est inférieure(ou supérieure) à un seuil que l'on aura fixé.

Par exemple le programme ci-dessous met à zéro les composantes rouges si elles sont inférieures à 127 et à 255 sinon (sans toucher aux autres composantes)

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
            if r<127:
16
                r=0
17
            else:
18
                r=255
19
            img2.pixels[index]=color(r,g,b)# remplissage de l'image vide
20
    image(img2,0,0)# affichage des images
21
    image(img,0,0,102,80)
  • Réalisez d'autres filtrages par seuil

ComplémentFiltrage par seuil (Edupython)

Le programme précédent adapté :

1
# Créé par vstep, le 31/01/2019 en Python 3.4
2
from PIL import Image
3
from pylab import *
4
5
# chargement des images
6
img=Image.open("joconde.png")
7
largeur,hauteur=img.size
8
#création d'une image vide
9
img2=Image.new('RGB',(largeur,hauteur))
10
11
#traitement
12
for y in range(hauteur):
13
    for x in range(largeur):
14
        r,v,b,a=img.getpixel((x,y))
15
        if r>127:
16
            r=255
17
        else:
18
            r=0
19
        img2.putpixel((x,y),(r,v,b))
20
21
22
#affichage
23
subplot(1,2,1)
24
xticks([]), yticks([])
25
title('La joconde')
26
plt.imshow(img)
27
28
subplot(1,2,2)
29
xticks([]), yticks([])
30
title('La joconde(filtre par seuil)')
31
plt.imshow(img2)
32
33
show()
  • Réalisez d'autres filtrages par seuil

DéfinitionModification par convolution (Processing)

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 (tout un programme ...)

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)      

ComplémentModification par convolution (Edupython)

Le même avec Edupython

1
# Créé par vstep, le 01/02/2019 en Python 3.4
2
from PIL import Image
3
from pylab import *
4
5
# chargement des images
6
img=Image.open("joconde.png")
7
largeur,hauteur=img.size
8
#création d'une image vide
9
img2=Image.new('RGB',(largeur,hauteur))
10
11
12
#traitement
13
for y in range(1,hauteur-1,1):
14
    for x in range(1,largeur-1,1):
15
        r1,v1,b1,a1=img.getpixel((x-1,y-1))
16
        r2,v2,b2,a2=img.getpixel((x,y-1))
17
        r3,v3,b3,a3=img.getpixel((x+1,y-1))
18
        r4,v4,b4,a4=img.getpixel((x-1,y))
19
        r5,v5,b5,a5=img.getpixel((x,y))
20
        r6,v6,b6,a6=img.getpixel((x+1,y))
21
        r7,v7,b7,a7=img.getpixel((x-1,y+1))
22
        r8,v8,b8,a8=img.getpixel((x,y+1))
23
        r9,v9,b9,a9=img.getpixel((x+1,y+1))
24
        #modification des pixels
25
        r=-r2-r4+5*r5-r6-r8
26
        v=-v2-v4+5*v5-v6-v8
27
        b=-b2-b4+5*b5-b6-b8
28
        img2.putpixel((x,y),(r,v,b))
29
30
31
32
#affichage
33
subplot(1,2,1)
34
xticks([]), yticks([])
35
title('La joconde')
36
plt.imshow(img)
37
38
subplot(1,2,2)
39
xticks([]), yticks([])
40
title('La joconde filtre passe haut')
41
plt.imshow(img2)
42
43
show()

SimulationRéaliser un flou par convolution

Pour réaliser un flou on utilise "la matrice" :

  • En modifiant le programme précédent, réalisez ce flou.

    avec Processing

    avec Edupython

Complément

  • Réalisez une autre transformation avec la matrice :

SimulationDétection des contours

Il s'agit encore d'une modification par convolution à réaliser avec cette image et cette matrice :

ComplémentSoyez créatifs

  • Inventez une transformation par convolution...

SimulationExtraction de contours

Téléchargez cette image[1]

Écrire ce programme dans EduPython.

Votre travail, l'expliquer...

1
from PIL import Image
2
from pylab import *
3
4
# chargement des images
5
img=Image.open("port.png")
6
largeur,hauteur=img.size
7
#création d'une image vide
8
img2=Image.new('RGB',(largeur,hauteur))
9
10
def distance(a,b,c,e,f,g):
11
    return (a-e)**2+(b-f)**2+(c-g)**2
12
13
#traitement
14
for y in range(1,hauteur-1,1):
15
    for x in range(1,largeur-1,1):
16
        r1,v1,b1,a1=img.getpixel((x-1,y-1))
17
        r2,v2,b2,a2=img.getpixel((x,y-1))
18
        r3,v3,b3,a3=img.getpixel((x+1,y-1))
19
        r4,v4,b4,a4=img.getpixel((x-1,y))
20
        r5,v5,b5,a5=img.getpixel((x,y))
21
        r6,v6,b6,a6=img.getpixel((x+1,y))
22
        r7,v7,b7,a7=img.getpixel((x-1,y+1))
23
        r8,v8,b8,a8=img.getpixel((x,y+1))
24
        r9,v9,b9,a9=img.getpixel((x+1,y+1))
25
        moyenne=distance(r5,v5,b5,r1,v1,b1) + distance(r5,v5,b5,r2,v2,b2)+distance(r5,v5,b5,r3,v3,b3)+distance(r5,v5,b5,r4,v4,b4)+distance(r5,v5,b5,r6,v6,b6)+distance(r5,v5,b5,r7,v7,b7)+distance(r5,v5,b5,r8,v8,b8)+distance(r5,v5,b5,r9,v9,b9)
26
        moyenne=moyenne//8
27
        if moyenne>250:
28
            img2.putpixel((x,y),(0,0,0))
29
        else:
30
            img2.putpixel((x,y),(255,255,255))
31
32
33
#affichage
34
subplot(1,2,1)
35
xticks([]), yticks([])
36
title('l\'originale')
37
plt.imshow(img)
38
39
subplot(1,2,2)
40
xticks([]), yticks([])
41
title('Ses contours')
42
plt.imshow(img2)
43
44
show()

SimulationModifications géométriques

Voici un programme qui 'renverse' la Joconde...

Processing

1
2
def calculindex(x,y):#le calcul de l'index
3
    return x+y*408
4
5
def setup():
6
    size(408,320)
7
    img=loadImage("data/joconde.png")
8
    img2=createImage(408,320,RGB)
9
    
10
    for x in range(0,408,1):
11
        for y in range(0,160,1):
12
            index1=calculindex(x,y)# calcul des index des pixels à inverser
13
            index2=calculindex(x,319-y)
14
            img2.pixels[index1]=img.pixels[index2]
15
            img2.pixels[index2]=img.pixels[index1]
16
    image(img2,0,0)
17
    image(img,0,0,102,80)

EduPython

1
# Créé par vstep, le 01/02/2019 en Python 3.4
2
from PIL import Image
3
from pylab import *
4
5
# chargement des images
6
img=Image.open("joconde.png")
7
largeur,hauteur=img.size
8
#création d'une image vide
9
img2=Image.new('RGB',(largeur,hauteur))
10
11
12
#traitement
13
for y in range(0,hauteur//2,1):
14
    for x in range(0,largeur,1):
15
        r1,v1,b1,a1=img.getpixel((x,y))
16
        r2,v2,b2,a2=img.getpixel((x,319-y))
17
        img2.putpixel((x,y),(r2,v2,b2))
18
        img2.putpixel((x,319-y),(r1,v1,b1))
19
20
#affichage
21
subplot(1,2,1)
22
xticks([]), yticks([])
23
title('La joconde')
24
plt.imshow(img)
25
26
subplot(1,2,2)
27
xticks([]), yticks([])
28
title('La joconde à l'envers')
29
plt.imshow(img2)
30
31
show()
32
33
34
35

Sauriez-vous obtenir ce résultat :

ComplémentÉlimination du 'bruit' dans une image

Voici une image avec du "bruit" : ( on a choisit une image en niveau de gris)

Pour éliminer le bruit on parcourt l'image et on remplace chaque pixel par la médiane de ce pixel et de ses 8 voisins.

C'est ce qu'on appelle un filtre médian.

Comme c'est une image en niveaux de gris, il suffit de le faire pour l'une des composantes ( par exemple le rouge)

  • On chargera les composantes rouges du pixel et de ses 8 voisins dans une liste.

  • On ordonnera cette liste, la médiane sera donc le 5ème élément (voir le cours de maths..)

Voilà le programme : (attention au nom de l'image téléchargée qui peut être différent de celle du programme..)

Processing

1
def calculindex(x,y):
2
    return x+y*256
3
4
def setup():
5
    size(512,256)
6
    img=loadImage("data/image-lena.png")
7
    img2=createImage(256,256,RGB)
8
    for x in range(1,255,1):
9
        for y in range(1,255,1):
10
            
11
            liste=[]#création de la liste
12
            index1=calculindex(x-1,y-1)
13
            index2=calculindex(x,y-1)
14
            index3=calculindex(x+1,y-1)
15
            index4=calculindex(x-1,y)
16
            index5=calculindex(x,y)
17
            index6=calculindex(x+1,y)
18
            index7=calculindex(x-1,y+1)
19
            index8=calculindex(x,y+1)
20
            index9=calculindex(x+1,y+1)
21
            liste.append(red(img.pixels[index1]))
22
            liste.append(red(img.pixels[index2]))
23
            liste.append(red(img.pixels[index3]))
24
            liste.append(red(img.pixels[index4]))
25
            liste.append(red(img.pixels[index5]))
26
            liste.append(red(img.pixels[index6]))
27
            liste.append(red(img.pixels[index7]))
28
            liste.append(red(img.pixels[index8]))
29
            liste.append(red(img.pixels[index9]))
30
            liste.sort()#tri de la liste
31
            r=liste[4]# on récupère le 5ème élément
32
            img2.pixels[index5]=color(r,r,r)
33
    image(img,0,0)
34
    image(img2,256,0)      

EduPython

1
# Créé par vstep, le 01/02/2019 en Python 3.4
2
from PIL import Image
3
from pylab import *
4
5
# chargement des images
6
img=Image.open("lenna.png").convert("RGB")
7
largeur,hauteur=img.size
8
#création d'une image vide
9
img2=Image.new('RGB',(largeur,hauteur))
10
print(largeur)
11
#traitement
12
13
for y in range(1,hauteur-1,1):
14
    for x in range(1,largeur-1,1):
15
        liste=[]
16
        r1,v1,b1=img.getpixel((x-1,y-1))
17
        liste.append(r1)
18
        r2,v2,b2=img.getpixel((x,y-1))
19
        liste.append(r2)
20
        r3,v3,b3=img.getpixel((x+1,y-1))
21
        liste.append(r3)
22
        r4,v4,b4=img.getpixel((x-1,y))
23
        liste.append(r4)
24
        r5,v5,b5=img.getpixel((x,y))
25
        liste.append(r5)
26
        r6,v6,b6=img.getpixel((x+1,y))
27
        liste.append(r6)
28
        r7,v7,b7=img.getpixel((x-1,y+1))
29
        liste.append(r7)
30
        r8,v8,b8=img.getpixel((x,y+1))
31
        liste.append(r8)
32
        r9,v9,b9=img.getpixel((x+1,y+1))
33
        liste.append(r9)
34
        liste.sort()
35
        r=liste[4]
36
        img2.putpixel((x,y),(r,r,r))
37
38
39
40
#affichage
41
subplot(1,2,1)
42
xticks([]), yticks([])
43
title('Lenna')
44
plt.imshow(img)
45
46
subplot(1,2,2)
47
xticks([]), yticks([])
48
title('Lenna_filtre médian')
49
plt.imshow(img2)
50
51
show()
52
  • Comment faire pour améliorer le résultat...

  1. cette image
PrécédentPrécédentSuivantSuivant
AccueilAccueilImprimerImprimer Stéphan Van Zuijlen Licence de documentation libre GNURéalisé avec Scenari (nouvelle fenêtre)