snt
Sciences Numériques et Technologie en classe de seconde au Lycée Saint-Exupéry de La Rochelle.
1827 : Première photo (Nicéphore Niépce)
1839 : Naissance officielle de la photographie (Louis Daguerre).
1855 : Mise au point d'un procédé pour capter les couleurs (James Clerk Maxwell) à la base du codage (RVB).
1861 : Première photo couleur (Thomas Sutton)
1957 : Première photo numérisée (Russell Kirsh) Définition : 176 x 176 (px)
1969 : Le capteur CCD (Charge Coupled Devise) révolutionne la photographie. (Willard Boyle & George smith) Ses photosites convertissent la lumière en signal électrique.
1975 : Premier appareil photo numérique portable (Steven Sasson)
2000 : Premiers téléphones portables avec appareil photo intégré (Sharp & Samsung) Démocratisation de la photographie numérique.
2020 : + de 1 000 000 000 000 de photos par an
Image numérique : image acquise, créée, traitée, stockée numériquement
Dimensions : taille de l'image en pouces...
ex. 12" 1 pouce = 2,54 cm
Définition : taille de l'image en pixels
ex. 640 \(\times\)480 px 4K = 4096 \(\times\)2160 px
Résolution : en dpi ou ppp
ex. 300 dpi
\(=\dfrac{définition}{dimension}\)
codage de couleur : nombre de bits par pixels (bpp)
Le poids de l'image est de 160 ko.
Le poids de l'image est de 300 ko.
Chaque pixel peut prendre environ 16,7 millions de couleurs possibles.
Environ 4,3 milliards de nuances possibles par pixel.
JPEG
TIFF
La bibliothèque PIL :
1. Charger l'image et saisir le programme
img.convert("L")
La "valeur" d'un pixel varie de 0 (le noir) à 255 (le blanc), c'est sa luminosité
2. Combien de transformations ?
im.transpose(Image.FLIP_LEFT_RIGHT)
im2.point(lambda i: i * 1.5)
La valeur de chaque pixel est multipliée par 1,5.
La méthode point(), permet d'agir sur chaque pixel.
3. Convertir en une image en niveaux de gris :
La conversion de l’image en couleurs en nuance de gris (“L’’) s’effectue selon la norme de l’UIT (Union Internationale des Télécommunications) ITU-R 601 par la formule suivante :
L = 0,299R + 0,587V + 0,114B
Dans la documentation de référence de Python (lien ci-dessous), voir la fonction Image.convert.
https://pillow.readthedocs.io/en/stable/reference/Image.html
4. à 7. Modifier et améliorer
Étape 1. Analyser un programme
La ligne 8 permet de convertir l’image en mode RGB ou RVB.
img_rgb = img.convert('RGB')
Cette ligne fusionne les trois canaux monobandes en une image multibandes en inversant les canaux rouge et vert.
2. Expliquez les lignes 14 et 16 du programme.
1. Que permet de réaliser la ligne 8 ?
inv_2 = Image.merge("RGB", (B,V,R))
inv_3 = Image.merge("RGB", (V,R,B))
Cette ligne fusionne les trois canaux monobandes en une image multibandes en inversant les canaux rouge et bleu.
Étape 2. Exécuter un programme et analyser les résultats
Ligne 9 #Convertit l’image en mode RGB ou RVB
Ligne 15 #Fusionne les trois canaux monobandes en une image multibandes en inversant les canaux rouge et bleu
Ligne 17 #Fusionne les trois canaux monobandes en une image multibandes en inversant les canaux rouge et vert
4. Ajoutez les commentaires manquants (lignes 9, 15 et 17) et exécutez le programme.
5. Observez et comparez les images A, B et C obtenues à partir de l’image d’origine (baby.jpeg). À quelles inversions correspondent-elles ?
L’image A correspond à l’inversion 2 : inversion entre le rouge et le bleu.
L’image B correspond à l’inversion 1 : inversion entre le vert et le bleu.
L’mage C correspond à l’inversion 3 : inversion entre le rouge et le vert.
Étape 3. Modifier un programme
from PIL import Image
img = Image.open("baby.jpeg")
R, V, B = img.split()
R = R.point(lambda i:i*1.5)
# Augmente l'intensité du canal rouge
inv2_R = Image.merge("RGB", (B,V,R))
inv2_R.save("inv2_avec_canal_R.jpg")
inv2_R.show()
6. Copiez-collez le programme et exécutez-le.
7. En exploitant le document 2, expliquez quelle est la différence entre l’image A (étape 2) et l’image D.
L’image D est obtenue par inversion entre les canaux rouge et bleu, elle correspond à l’inversion 2 avec comme différence l’augmentation de la luminosité du canal rouge avant transformation.
Le facteur lambda appliqué est de 1,5 et la différence avec l’image A est très légère. On peut distinguer les quelques différences de rendu au niveau du contraste d’ensemble et au niveau de la couleur des yeux.
8. Proposez une ou d’autres modifications, observez et commentez les résultats.
On peut faire plusieurs modifications et transformations en appliquant des facteurs lambdas différents avant les inversions. On donne ci-dessous l’exemple de l’inversion 3 (entre le rouge et le vert) mais avec un lambda de 3 appliqué au canal vert avant inversion.
from PIL import Image
img = Image.open("baby.jpeg")
# Ouvre la photo et la stocke dans la variable img
R, V, B = img.split()
# Retourne un tuple contenant toutes les bandes de l’image
V = V.point(lambda i:i*3)
# Multiplie l’intensité du canal vert par 3
inv3_V = Image.merge("RGB", (V,R,B))
# Fusionne les 3 canaux monobande en une image multibandes en inversant les canaux
inv3_V.save("inv3 avec_canal_V.png")
# Sauvgarde l’image inv3_V (avec augmentation de l’intensité du canal vert)
inv3_V.show()
# Affiche l’image
# *********** Découper l’image ***********
from PIL import Image
from PIL import ImageFilter
img = Image.open('garçon.jpg')
img.show()
print("LxH:", img.size)
xa = 1741; ya = 0; xb = 3979; yb = 2388
rectangle = (xa,ya,xb,yb)
decoupe = img.crop(rectangle)
decoupe.show()
print("lxh:", decoupe.size)
decoupe.save("image_decoupee.png")
# *********** Appliquer un filtre ***********
img2 = Image.open('image_decoupee.png')
im_filtree = img2.filter(ImageFilter.CONTOUR)
im_filtree.show()
im_filtree.save('image_filtree.png')
Ajouter aux emplacements judicieux, les lignes de commentaires données dans le désordre...
# *********** Découper l’image ***********
from PIL import Image
# Charge le module Image depuis PIL
from PIL import ImageFilter
# Charge le module ImageFiler de PIL
img = Image.open('garçon.jpg')
# Charger l’image
img.show()
# Afficher l’image d’origine
print("LxH:", img.size)
# Afficher la définition de l’image d’origine
xa = 1741; ya = 0; xb = 3979; yb = 2388
# Définir les coordonnées des points a et b
rectangle = (xa,ya,xb,yb)
# Définir la zone de découpage
decoupe = img.crop(rectangle)
# Réaliser la découpe
decoupe.show()
# Afficher l’image découpée
print("lxh:", decoupe.size)
# Afficher la définition de l’image découpée
decoupe.save("image_decoupee.png")
# Enregistrer l’image découpée
# *********** Appliquer un filtre ***********
img2 = Image.open('image_decoupee.png')
# Charger l’image découpée
im_filtree = img2.filter(ImageFilter.CONTOUR)
# Appliquer un filtre (ici CONTOUR)
im_filtree.show()
# Afficher l’image filtrée
im_filtree.save('image_filtree.png')
# Enregistrer l’image filtrée
Exécuter le script.
4. Exprimez la largeur l de l’image découpée en fonction de xa et xb. Calculez sa valeur.
5. Exprimez la hauteur h de l’image découpée en fonction de ya et yb. Calculez sa valeur.
Largeur : l = xb – xa soit l = 3 979 – 1 741 = 2 238 px
Hauteur = yb – ya soit h = 2388 – 0 = 2 388 pixels
6. Essayez en modifiant la ligne concernée du programme, d’autres filtres à la place de CONTOUR : BLUR, DETAIL, EDGE_ENHANCE, EDGE_ENHANCE_MORE, EMBOSS, FIND_EDGES, SHARPEN, SMOOTH...
EMBOSS
from PIL import Image
im = Image.open('Chap8_chat.jpg')
largeur = im.size[0]
hauteur = im.size[1]
im2 = Image.new('RGB', (largeur,hauteur))
print(largeur,hauteur)
for lig in range(hauteur):
for col in range(largeur):
(r,g,b) = im.getpixel((col,lig))
im2.putpixel((col,lig), (0,0,b))
im2.save('Chap8_chatbleu.jpg')
Script à modifier
Explications : Ouverture de l’image, obtention de sa largeur et de sa hauteur. Création de l'image résultat (pour l'instant vide) de même définition.
Puis deux boucles imbriquées pour parcourir ligne à ligne les pixels de l’image d'origine. L’écriture de l’image résultat du traitement s’effectue par des instructions spécifiques permettant de positionner les pixels un par un puis de sauvegarder le résultat dans un fichier.
from PIL import Image
im = Image.open('Chap8_chat.jpg')
largeur = im.size[0]
hauteur = im.size[1]
im2 = Image.new('RGB', (largeur,hauteur))
print(largeur,hauteur)
for lig in range(hauteur):
for col in range(largeur):
(r,g,b) = im.getpixel((col,lig))
im2.putpixel((col,lig), (0,0,b))
im2.save('Chap8_chatbleu.jpg')
Script à modifier
Solution & explications
Pour chaque pixel de l’image à calculer, il faut parcourir les huit voisins de l’image donnée pour décider si un contour doit être marqué à ce point-là.
def dist(r1,g1,b1, r2,g2,b2):
return((r2-r1)**2 + (g2-g1)**2 + (b2-b1)**2)
from PIL import Image
im = Image.open('Chap8_Sauzon.jpg')
largeur = im.size[0]
hauteur = im.size[1]
im2 = Image.new('RGB', (largeur,hauteur))
print(largeur,hauteur)
for lig in range(1, hauteur-1):
for col in range(1, largeur-1):
(r,g,b) = im.getpixel((col,lig))
d = 0
for i in range(-1,2):
for j in range (-1,2):
(rv,gv,bv) = im.getpixel((col+i,lig+j))
d += dist(r,g,b,rv,gv,bv)
if d > 2000:
im2.putpixel((col,lig), (0,0,0))
else:
im2.putpixel((col,lig), (255,255,255))
im2.save('Chap8_SauzonContours.jpg')
La double boucle notée en gras permet d’énumérer les 9 pixels voisins en ajoutant – 1, 0 ou 1 aux indices de ligne et de colonne du pixel à étudier et d’additionner leurs distances de couleur avec ce pixel.
Au lieu de tester la moyenne des 8 par rapport au seuil de 250, on a simplifié en comparant directement la somme à 2 000.
Selon le résultat de la comparaison, un pixel noir (0,0,0) ou un pixel blanc (255,255,255) est noté dans l’image résultat.
By snt