4 - Filtrage d'une image
Nous allons voir comment modifier les pixels des photos pour obtenir différents effets.
Mise en évidence d'une couleur, transformation en noir et blanc, détection de contour ...
Cela vous permettra de voir ce qu'on peut faire avec un langage de programmation comme Python.
1 - Prise en main de Thonny
Thonny permet de travailler avec Python dans un environnement qui permet de voir le contenu des variables, et d'avoir dans la même fenêtre le Shell (le mode commande interactive en direct) et la fenêtre de programmation (celle où on tape du code pour l'enregistrer).

01° Ouvrir Thonny.
Dans le menu View, sélectionner variables en plus du Shell.
02° Taper le code suivant dans la partie programme (celle du haut, sans les trois chevrons >>>).
1
2 | largeur = 1000
hauteur = 250
|
Nous venons de créer deux variables : on pourra maintenant récupérer les valeurs stockées en tapant simplement les noms des variables.
03° Sauvegarder le programme dans votre répertoire et lancer le programme en appuyant sur la flèche verte.
Il ne devrait rien se passer sauf la création des deux variables dans la fenêtre de gauche.

04° Tapez les instructions suivantes dans le Shell (la partie avec les trois chevrons >>>).
>>> largeur
1000
>>> hauteur
250
>>> pixels = largeur * hauteur
>>> pixels
250000
Vous pourrez voir également le contenu de pixels dans la partie variables à partir du moment où la variable est déclarée.

L'intérêt de Python par rapport à Scratch ? La création de fonction. Dans Scratch, s'il n'existe pas de bloc capable de faire ce que vous voulez faire, vous ne pourrez pas réaliser le programme de vos rêves.
Avec les langages de programmation, il suffit de créer une fonction :
- On lui envoie des ENTREES qu'on récupère dans des variables (qu'on nomme les paramètres)
- On calcule ce qu'on veut à partir des entrées et on renvoie la SORTIE (le résultat) avec le mot-clé return
- On pourra stocker le résultat de la fonction dans une variable si on le désire
1
2
3
4 | def calculer_taille(lar, hau):
'''Renvoie la taille en pixels d'une image dont on connait la largeur et la hauteur en pixels'''
taille = lar * hau
return taille
|
05° Modifier la partie programme puis enregistrer le.
Il ne devrait rien se passer SAUF qu'une nouvelle variable est apparue dans l'onglet VARIABLE : celle qui porte le nom de la fonction calculer_taille.
1
2
3
4
def calculer_taille(lar, hau):
'''Renvoie la taille en pixels d'une image dont on connait la largeur et la hauteur en pixels'''
taille = lar * hau
return taille

06° Tapez les instructions suivantes dans le Shell (la partie avec les trois chevrons >>>).
>>> calculer_taille(1000, 250)
250000
Le Shell vous montre la réponse mais est-elle mémorisée dans la partie variable ?

07° Pour mémoriser le résultat de façon à le réutiliser plus tard, il suffit de placer la réponse de la fonction dasn ... une variable. Tapez instructions suivantes dans le Shell (la partie avec les trois chevrons >>>).
>>> reponse = calculer_taille(1000, 250)
>>> reponse
250000
Une variable reponse contient maintenant la valeur stockée.

2 - Gestion des images avec Python
Nous allons maintenant manipuler des images et changer les valeurs RGB des différents pixels.
Nous avons vu dans l'activité précédente qu'une image n'est qu'une succession de nombres.
Pour manipuler les images avec Python et Thonny, il faut possèder un module spécifique, qui gère les images : Pillow.
Commençons par voir si vous avez le module.
08° Tapez ceci dans le Shell pour voir si cela déclenche une erreur.
>>> from PIL import Image
Si c'est le cas :
- Ouvrir le menu Tool/Outils en haut vers la droite dans Thonny
- Sélectionner Manage Packages/Gérer les Paquets
- Faire une recherche sur Pillow puis installer la bibliothèque. Ca peut être un peu long.

09° Téléchargez une image de type png ou jpg sur le Web et placez la dans un dossier nommé SNT-photographie. Choisissez une image possèdant pas mal de couleurs différentes si possible.
10° Enregistrer le programme ci-dessous (après avoir lu la remarque ATTENTION) avec Thonny en le plaçant dans le même répertoire SNT-photographie que votre image. ATTENTION : il faudra modifier le nom du fichier stocké dans la variable base de façon à ce qu'il corresponde à celui de votre fichier-image.
📁 SNT-photographie
📄 votre_programme.py
📄 votre_image.png
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78 |
|
Vous n'aurez qu'à apporter des modifications sur ces parties du programme (notamment le nom du fichier image de base) :
1
2
3
4
5
6
..
64
65
66
67
68
69 | from PIL import Image as Img
# Nom du fichier-image original
base = "maisons.jpg"
# Nom du fichier-image modifié
sauvegarde = "modification.jpg"
def filtrage(r, g, b):
'''Fonction qui renvoie des valeurs r, g, b après les avoir modifiées'''
rouge = b # On place la valeur b dans rouge
vert = g # On laisse la valeur g dans vert
bleu = r # On place la valeur r dans bleu
return (rouge, vert, bleu)
|
11° Lancer votre programme. Si une erreur apparaît (en rouge), lire le message.
Souvent :
- soit vous n'avez pas installé le module Pillow !
- soit vous n'avez pas modifié le nom associé à la variable base
- soit vous n'avez pas mis votre image et votre fichier Python dans le même répertoire
Si vous bloquez, faire appel à l'enseignant.
Vous devriez avoir une image à l'écran, mais une image où les intensités bleu et le rouge ont été inversées : voir les lignes suivantes
66
67
68 | rouge = b # On place la valeur b dans rouge
vert = g # On laisse la valeur g dans vert
bleu = r # On place la valeur r dans bleu
|
Exemple avec une image contenant beaucoup de rouge et d'orange :

Et qui devient une image contenant beaucoup de bleu et de cyan :

Bon et comment vérifier que ça marche autrement qu'en regardant les images ? En utilisant la fonction pixel qu'on vous offre ligne 8.
12° Utiliser les commandes suivantes dans la Console (le Shell dans la version anglaise) pour voir les valeurs des intensités R, G et B sur le pixel en x=50 et y = 100 par exemple.
>>> pixel(base, 50, 100)
'Pixel de coordonnées (50, 100) : R = 160 - G = 174 - B = 3'
>>> pixel(sauvegarde, 50, 100)
'Pixel de coordonnées (50, 100) : R = 3 - G = 174 - B = 160'
Visualiser que le programme est bien parvenu à intervertir les deux valeurs sur ce pixel.
Image JPEG : les images JPEG prennent moins de place en mémoire car on réduit le nombre de couleurs disponibles. Il est donc possible que les deux valeurs interverties ne soient pas exactement les mêmes si vous avez utilisé ce format.
13° Comparer l'appel à la fonction et la déclaration de la fonction (son prototype)
L'appel :
>>> pixel(base, 50, 100)
La déclaration :
8 | def pixel(nom, x, y):
|
Questions
- Dans quelle variable va se stocker la variable base ?
- Dans quelle variable va se stocker la valeur 50 ?
- Dans quelle variable va se stocker la valeur 100 ?
...CORRECTION...
Il faut associer place par place :

On voit donc qu'on stocke base
dans nom
, 50
dans x
et 100
dans y
.
C'est comme si cet appel précis avait été fait en notant ceci en début de la fonction :
nom = base
x = 50
y = 100
14° Comparer l'appel à la fonction et la déclaration de la fonction (son prototype)
L'appel :
>>> pixel(sauvegarde, 300, 40)
La déclaration :
8 | def pixel(nom, x, y):
|
...CORRECTION...
C'est comme si cet appel précis avait été fait en notant ceci en début de la fonction :
nom = sauvegarde
x = 300
y = 40
Que fait la fonction filtrage ? Pour l'instant, elle inverse les valeurs des intensités R et B.
Regardons comment nous pourrions l'utiliser.
3 - Filtrage
Filtrer les couleurs veut dire en laisser passer certaines et pas d'autres.
Pour l'instant, nous intervertissons le rouge et le bleu sur chaque pixel dans la fonction filtrage :
64
65
66
67
68
69 | def filtrage(r, g, b):
'''Fonction qui renvoie des valeurs r, g, b après les avoir modifiées'''
rouge = b # On place la valeur b dans rouge
vert = g # On laisse la valeur g dans vert
bleu = r # On place la valeur r dans bleu
return (rouge, vert, bleu)
|
14° CREER UN FILTRE ROUGE : cela veut dire que la fonction filtre ne doit renvoyer que la bonne intensité rouge de départ et mettre les autres à 0.

Et qui devient une image ne contenant que les intensités rouges :

L'une à côté de l'autre :
...CORRECTION...
64
65
66
67
68
69 | def filtrage(r, g, b):
'''Fonction qui renvoie des valeurs r, g, b après les avoir modifiées'''
rouge = r
vert = 0
bleu = 0
return (rouge, vert, bleu)
|
15° CREER UN FILTRE BLEU : cela veut dire que la fonction filtre ne doit renvoyer que la bonne intensité bleue de départ et mettre les autres à 0.

Et qui devient une image ne contenant que les intensités bleues :

L'une à côté de l'autre :
...CORRECTION...
64
65
66
67
68
69 | def filtrage(r, g, b):
'''Fonction qui renvoie des valeurs r, g, b après les avoir modifiées'''
rouge = r
vert = 0
bleu = 0
return (rouge, vert, bleu)
|
16° CREER UN FILTRE VERT : cela veut dire que la fonction filtre ne doit renvoyer que la bonne intensité verte de départ et mettre les autres à 0.

Et qui devient une image ne contenant que les intensités vertes :

L'une à côté de l'autre :
...CORRECTION...
64
65
66
67
68
69 | def filtrage(r, g, b):
'''Fonction qui renvoie des valeurs r, g, b après les avoir modifiées'''
rouge = 0
vert = g
bleu = 0
return (rouge, vert, bleu)
|
17° IMAGE GRISE : Remplacer les trois intensités R, G et B par la moyenne des trois. On pourra utiliser la division euclidienne en Python en utilisant //
plutôt que simplement /
.
Par exemple rouge = (r+g+b) // 3
Si les trois intensités ont la même valeur, votre oeil percevra du gris.

Et qui devient une image grise :

L'une à côté de l'autre :
...CORRECTION...
64
65
66
67
68
69 | def filtrage(r, g, b):
'''Fonction qui renvoie des valeurs r, g, b après les avoir modifiées'''
rouge = (r + g + b) // 3
vert = (r + g + b) // 3
bleu = (r + g + b) // 3
return (rouge, vert, bleu)
|
Si on veut transformer une image en couleur en réelle perception grisée pour un oeil humain, il faut utiliser des formules particulières pour avoir un rendu correct car nos yeux ne sont pas sensibles de la même manière à la lumière rouge, verte ou bleue. ils sont beaucoup plus sensibles à la lumière verte qu'aux lumières bleues et rouges.
18° IMAGE GRISE HUMAINE : Remplacer les trois intensités R, G et B par red = (21*r + 71*g + 8*b) // 100
.

La nouvelle version grise à gauche, la moyenne pure à droite :
...CORRECTION...
64
65
66
67
68
69 | def filtrage(r, g, b):
'''Fonction qui renvoie des valeurs r, g, b après les avoir modifiées'''
rouge = (21*r + 71*g + 8*b) // 100
vert = (21*r + 71*g + 8*b) // 100
bleu = (21*r + 71*g + 8*b) // 100
return (rouge, vert, bleu)
|
4 - FAQ
Pas de question pour le moment
Activité publiée le 02 12 2019
Dernière modification : 08 12 2019
Auteur : ows. h.