Pourquoi traiter une image en niveaux de gris
Convertir une image couleur en niveaux de gris consiste à remplacer les trois nombres de chaque pixel par un seul : sa luminosité.
Presque tous les traitements d’image commencent par là. Un seul nombre par pixel est plus simple à comparer, à seuiller et à compter que trois.
À la fin de cette leçon
Remarque
Je peux convertir un pixel couleur en niveau de gris avec les poids de la luminance.
Mots clés
| Mot | Ce que ça veut dire |
|---|---|
| RVB | rouge, vert, bleu : les trois canaux d’un pixel couleur |
| Luminance | la clarté perçue d’une couleur, un seul nombre |
| Moyenne pondérée | une moyenne où chaque valeur compte plus ou moins |
| Poids | le coefficient qui dit combien compte un canal |
| Niveau de gris | un nombre de 0 (noir) à 255 (blanc) |
| Arrondi | le passage à l’entier le plus proche |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
La luminance est une moyenne pondérée
Pour passer au gris, on ne fait pas la moyenne simple des trois canaux. L’œil perçoit le vert plus clair que le rouge, et le rouge plus clair que le bleu.
On calcule donc : gris = 0,299 fois le rouge, plus 0,587 fois le vert, plus 0,114 fois le bleu. Les trois poids font 1 : un pixel blanc reste blanc. Pillow utilise ces poids dans convert("L").
Exemple travaillé : cinq pixels en gris
| Pixel (R, V, B) | Rouge × 0,299 | Vert × 0,587 | Bleu × 0,114 | Gris arrondi |
|---|---|---|---|---|
| (255, 0, 0) | 76,2 | 0 | 0 | 76 |
| (0, 255, 0) | 0 | 149,7 | 0 | 150 |
| (0, 0, 255) | 0 | 0 | 29,1 | 29 |
| (197, 157, 62) | 58,9 | 92,2 | 7,1 | 158 |
| (255, 255, 255) | 76,2 | 149,7 | 29,1 | 255 |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Pondérée contre moyenne simple
docker exec jupyter python3 -c "print(round(0.299 * 197 + 0.587 * 157 + 0.114 * 62), round((197 + 157 + 62) / 3))"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Convertir trois pixels à la main
# Trois pixels (rouge, vert, bleu), convertis en un niveau de gris.
pixels = [[255, 0, 0], [0, 255, 0], [30, 90, 200]]
for pixel in pixels:
gris = 0.299 * pixel[0] + 0.587 * pixel[1] + 0.114 * pixel[2]
print(pixel, "donne", round(gris))
# Ajoutez le pixel [120, 120, 120] à la liste, puis relancez.
# Un pixel dont les trois canaux sont égaux garde-t-il sa valeur ?
Une erreur fréquente
Attention
Beaucoup pensent que le gris est la moyenne simple du rouge, du vert et du bleu. Pour le pixel doré, la moyenne simple donne 139 et la luminance 158. Utilisez les poids chaque fois que la clarté perçue compte.
Chaque canal se lit séparément
Un canal est une image à un seul nombre par pixel. Avec Pillow, split() rend les trois canaux d’une image RGB. Lire le rouge, le vert et le bleu d’un même pixel redonne ses trois nombres.
On peut ainsi traiter un seul canal. Le vert, le plus pondéré, ressemble déjà beaucoup à la version en gris.
Séparer les trois canaux d’un pixel
docker exec jupyter python3 -c "from PIL import Image; r,v,b=Image.open('images/coins.png').split(); print(r.getpixel((50, 50)), v.getpixel((50, 50)), b.getpixel((50, 50)))"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Convertir toute l’image en une ligne
Le script grey.py ouvre coins.png, la convertit avec convert("L") et compare un pixel avant et après. Il compte aussi les pixels de chaque bande de gris et enregistre coins_grey.png.
Les mots affichés sont en anglais : colour veut dire couleur, grey gris, pixels from 0 to 63 les pixels de 0 à 63.
Convertir coins.png avec grey.py
docker exec jupyter python3 steps/grey.pyAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Pour aller plus loin
Dans votre carnet, ouvrez coins_grey.png et comparez-la à coins.png. Puis calculez le gris du pixel (50, 50) avec la moyenne simple, et comparez avec 158.
Les deux images semblent-elles différentes à l’œil ? Dites en une phrase pourquoi la différence compte pour un seuil.