Exercices sur les images☘
Ces exercices doivent être utilisés pour vous entraîner à programmer. Ils sont généralement accompagnés d'aide et de leur solution pour vous permettre de progresser.
Avant de vous précipiter sur ces solutions dès la première difficulté, n'oubliez pas les conseils suivants :
- Avez-vous bien fait un schéma au brouillon pour visualiser le problème posé ?
- Avez-vous essayé de rédiger un algorithme en français, avec vos propres mots, avant de vous lancer dans la programmation sur machine ?
- Avez-vous utilisé des affichages intermédiaires, des
print()
, pour visualiser au fur et à mesure le contenu des variables ? - Avez-vous testé le programme avec les propositions de tests donnés dans l'exercice ?
- Avez-vous testé le programme avec de nouveaux tests, différents de ceux proposés ?
Rappels
- Chaque programme Python doit être sauvegardé sous forme de fichier texte
avec l'extension
.py
.
Enregistrez ce fichier dans le dossier[B03-Images]
avec le nom donné à l'exercice :ProgB03.51.py
,ProgB03.52.py
, etc... - Pour exécuter ce programme, il suffit de le sauvegarder puis d'appuyer
sur la touche
[F5]
.
ProgB03.51 - Une seule composante☘
On considère l'image feux.png
ci-contre.
-
A l'aide d'un clic droit sur cette image, enregistrez-là dans le répertoire
[B03-Images]
. -
Copiez/collez et complétez la définition de la fonction
composantes()
qui crée et sauvegarde une image constituée uniquement des composantes rouge, vert ou bleu de l'image d'origine selon la valeur du paramètreindice
.
Les autres composantes sont mises à zéro.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
from PIL import Image def composantes(source, indice, nom_result): """ source - Image indice - int, entier compris entre 0 et 2 (0 -> R, 1 -> G, 2 -> B) nom_result - str, nom du fichier image qui sera renvoyé Sortie: Image - Nouvelle image de mêmes caractéristiques que la source. Seule la composante de numéro indice est conservée, les autres sont mises à zéro. """ # TODO if __name__ == '__main__': # importation de l'image: source = Image.open('feux.png') composantes(source, 0, 'feux_rouge.png') composantes(source, 1, 'feux_vert.png') composantes(source, 2, 'feux_bleu.png')
Exemples
L'instruction
composantes(source, 0, 'feux_rouge.png')
renvoie l'image :L'instruction
composantes(source, 1, 'feux_vert.png')
renvoie l'image :L'instruction
composantes(source, 2, 'feux_bleu.png')
renvoie l'image :Une solution
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
from PIL import Image def composantes(source, indice, nom_result): """ source - Image indice - int, entier compris entre 0 et 2 (0 -> R, 1 -> G, 2 -> B) nom_result - str, nom du fichier image qui sera renvoyé Sortie: Image - Nouvelle image de mêmes caractéristiques que la source. Seule la composante de numéro indice est conservée, les autres sont mises à zéro. """ # récupération des dimensions de l'image : largeur, hauteur = source.size resultat = Image.new(source.mode, source.size) for ligne in range(hauteur): for colonne in range(largeur): r, g, b = source.getpixel( (colonne, ligne) ) if indice == 0: resultat.putpixel( (colonne, ligne), (r, 0, 0) ) elif indice == 1: resultat.putpixel( (colonne, ligne), (0, g, 0) ) else: resultat.putpixel( (colonne, ligne), (0, 0, b) ) resultat.save(nom_result) if __name__ == '__main__': # importation de l'image: source = Image.open('feux.png') composantes(source, 0, 'feux_rouge.png') composantes(source, 1, 'feux_vert.png') composantes(source, 2, 'feux_bleu.png')
ProgB03.52 - Rechercher des informations☘
Dans cet exercice, on utilise à nouveau l'image de l'exercice précédent.
-
Copiez/collez et complétez le corps de la fonction
sommetHaut()
en respectant ses spécifications.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
from PIL import Image def sommetHaut(source): """ source - Image Sortie: tuple - couple de coordonnées du premier pixel rencontré de couleur distincte de (255, 255, 255). L'image est parcourue de haut en bas et de gauche à droite. →→→→ →→→→ →→→→ """ if __name__ == '__main__': # importation de l'image: source = Image.open('feux.png') print(f"Coordonnées du sommet haut du triangle : {sommetHaut(source)}\n")
Une piste
N'oubliez pas de récupérer les dimensions de l'image dans le code de la fonction
sommetHaut()
Un algorithme
Parcourir les pixels ligne par ligne de gauche à droite S'arrêter dès que l'on a obtenu un pixel dont la couleur n'est pas blanche Renvoyer les coordonnées de ce pixel
Une autre piste
La condition « tant que le pixel est blanc » pourra se traduire par :
oùwhile source.getpixel((colonne,ligne)) == (255,255,255):
colonne
etligne
sont deux variables à faire évoluer,colonne
entre0
etlargeur-1
,ligne
entre0
ethauteur-1
(oùlargeur
est la largeur de l'image ethauteur
sa hauteur).Une solution avec une double boucle
for
On obtient le pixel de coordonnées
(249, 20)
.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
from PIL import Image def sommetHaut(source): """ source - Image Sortie: tuple - couple de coordonnées du premier pixel rencontré de couleur distincte de (255, 255, 255). L'image est parcourue de haut en bas et de gauche à droite. →→→→ →→→→ →→→→ """ # récupération des dimensions de l'image : largeur, hauteur = source.size for ligne in range(hauteur): for colonne in range(largeur): if source.getpixel((colonne,ligne)) != (255,255,255): return (colonne, ligne) if __name__ == '__main__': # importation de l'image: source = Image.open('feux.png') print(f"Coordonnées du sommet haut du triangle : {sommetHaut(source)}\n")
Une solution avec une boucle
while
On obtient aussi le pixel de coordonnées
(249, 20)
.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
from PIL import Image def sommetHaut(source): """ source - Image Sortie: tuple - couple de coordonnées du premier pixel rencontré de couleur distincte de (255, 255, 255). L'image est parcourue de haut en bas et de gauche à droite. →→→→ →→→→ →→→→ """ # récupération des dimensions de l'image : largeur, hauteur = source.size ligne = 0 colonne = 0 while source.getpixel((colonne,ligne)) == (255,255,255): if colonne < largeur-1: colonne += 1 else: colonne = 0 ligne += 1 return (colonne, ligne) if __name__ == '__main__': # importation de l'image: source = Image.open('feux.png') print(f"Coordonnées du sommet haut du triangle : {sommetHaut(source)}\n")
-
À la fin du «
main
» du programme précédent, ajoutez les instructions suivantes :
Exécutez le programme puis interprétez le résultat obtenu.34 35 36
for i in range(largeur): if source.getpixel((i, 20)) != (255, 255, 255): print(i)
Une solution
On obtient :
Cela signifie que le sommet de notre triangle est en fait constitué de deux pixels, le pixel de coordonénes249 250
(249, 20)
et celui de coordonnées(250, 20)
.Vous pouvez vous convaincre de ce résultat en ouvrant l'image avec le logiciel
GIMP
. Dans le menu [Affichage], sélectionnez [Zoom 16:1].
Déplacez-vous sur les pixels du sommet, les coordonnées s'affichent dans le bas de la fenêtre du logiciel. -
Obtenir de même les coordonnées du sommet bas-gauche du triangle et celles du sommet bas-droite.
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
from PIL import Image def sommetBasGauche(source): """ source - Image Sortie: tuple - couple de coordonnées du premier pixel bas-gauche rencontré de couleur distincte de (255, 255, 255). """ # TODO def sommetBasDroite(source): """ source - Image Sortie: tuple - couple de coordonnées du premier pixel bas-droite rencontré de couleur distincte de (255, 255, 255). """ # TODO if __name__ == '__main__': # importation de l'image: source = Image.open('feux.png') print(f"Coordonnées du sommet bas-gauche du triangle : {sommetBasGauche(source)}\n") print(f"Coordonnées du sommet bas-droite du triangle : {sommetBasDroite(source)}\n")
Une piste
Au lieu de parcourir l'image ligne par ligne, on peut la parcourir colonne par colonne :
- De gauche à droite pour le sommet bas-gauche ;
- De droite à gauche et de bas en haut pour le sommet bas-droit.
A vous de traduire cela avec les modifications qui conviennent sur le code écrit pour le sommet haut.
Une solution avec une double boucle
for
Le pixel bas-gauche a pour coordonnées
(46, 364)
, les coordonnées du sommet bas-droite sont(453, 364)
.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
from PIL import Image def sommetBasGauche(source): """ source - Image Sortie: tuple - couple de coordonnées du premier pixel bas-gauche rencontré de couleur distincte de (255, 255, 255). L'image est parcourue de gauche à droite et de haut en bas. ↓↓↓↓ ↓↓↓↓ ↓↓↓↓ """ # récupération des dimensions de l'image : largeur, hauteur = source.size for colonne in range(largeur): for ligne in range(hauteur): if source.getpixel((colonne,ligne)) != (255,255,255): return (colonne, ligne) def sommetBasDroite(source): """ source - Image Sortie: tuple - couple de coordonnées du premier pixel bas-droite rencontré de couleur distincte de (255, 255, 255). L'image est parcourue de bas en haut et de droite à gauche. ↑↑↑↑ ↑↑↑↑ ↑↑↑↑ """ # récupération des dimensions de l'image : largeur, hauteur = source.size for colonne in range(largeur-1, -1, -1): for ligne in range(hauteur-1, -1, -1): if source.getpixel((colonne,ligne)) != (255,255,255): return (colonne, ligne) if __name__ == '__main__': # importation de l'image: source = Image.open('feux.png') print(f"Coordonnées du sommet bas-gauche du triangle : {sommetBasGauche(source)}\n") print(f"Coordonnées du sommet bas-droite du triangle : {sommetBasDroite(source)}\n")
Une solution avec une boucle
while
Le pixel bas-gauche a pour coordonnées
(46, 364)
, les coordonnées du sommet bas-droite sont(453, 364)
.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
from PIL import Image def sommetBasGauche(source): """ source - Image Sortie: tuple - couple de coordonnées du premier pixel bas-gauche rencontré de couleur distincte de (255, 255, 255). L'image est parcourue de gauche à droite et de haut en bas. ↓↓↓↓ ↓↓↓↓ ↓↓↓↓ """ # récupération des dimensions de l'image : largeur, hauteur = source.size ligne = 0 colonne = 0 while source.getpixel((colonne,ligne)) == (255,255,255): if ligne < hauteur-1: ligne += 1 else: ligne = 0 colonne += 1 return (colonne, ligne) def sommetBasDroite(source): """ source - Image Sortie: tuple - couple de coordonnées du premier pixel bas-droite rencontré de couleur distincte de (255, 255, 255). L'image est parcourue de bas en haut et de droite à gauche. ↑↑↑↑ ↑↑↑↑ ↑↑↑↑ """ # récupération des dimensions de l'image : largeur, hauteur = source.size ligne = hauteur-1 colonne = largeur-1 while source.getpixel((colonne,ligne)) == (255,255,255): if colonne > 0: colonne = colonne-1 else: colonne = largeur-1 ligne = ligne - 1 return (colonne, ligne) if __name__ == '__main__': # importation de l'image: source = Image.open('feux.png') print(f"Coordonnées du sommet bas-gauche du triangle : {sommetBasGauche(source)}\n") print(f"Coordonnées du sommet bas-droite du triangle : {sommetBasDroite(source)}\n")
ProgB03.53 - Une image à partir de rien☘
Concevoir un script, sans fonction, qui permet d'obtenir le rectangle ci-contre, de 100 pixels de largeur et de 256 pixels de hauteur, de couleur dégradée du noir (en haut) vers le rouge (en bas).
Une piste : fichier à compléter
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
Une solution
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
ProgB03.54 - Carrés empilés☘
L'image ci-contre est constituée de sept carrés de couleur noir, rouge, vert, jaune, bleu, magenta et cyan (dans cet ordre).
-
Rappelez les triplets RGB correspondant à chacune de ces couleurs.
Réponse
Couleur Composante R Composante G Composante B Noir 0
0
0
Rouge 255
0
0
Vert 0
255
0
Jaune 255
255
0
Bleu 0
0
255
Magenta 255
0
255
Cyan 0
255
255
-
Copiez/collez et complétez la définition de la fonction
carre()
en respectant ses spécifications.1 2 3 4 5 6 7 8
def carre(source, h, couleur): """ source – Image h - int, ordonnée (numéro de ligne couleur – tuple, triplet RGB Sortie : None – Ajoute à l'image source un carré de 100 pixels de couleur, à partir de l'ordonnée h. """
Une solution
1 2 3 4 5 6 7 8 9 10 11
def carre(source, h, couleur): """ source – Image h - int, ordonnée (numéro du carré - de 0 à 6) couleur – tuple, triplet RGB Sortie : None – Ajoute à l'image source un carré de 100 pixels de couleur, à partir de l'ordonnée h. """ for x in range(100) : for y in range(h*100, (h+1)*100) : source.putpixel((x, y), couleur)
-
Utilisez cette fonction pour obtenir l'image de carrés empilés.
Une solution
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
##----- Importation des Modules -----## from PIL import Image # Ne pas oublier de l'importer pour un programme indépendant ##------ Définition des Fonctions ------## def carre(source, h, couleur): """ source – Image h - int, ordonnée (numéro du carré - de 0 à 6) couleur – tuple, triplet RGB Sortie : None – Ajoute à l'image source un carré de 100 pixels de couleur, à partir de l'ordonnée h. """ for x in range(100) : for y in range(h*100, (h+1)*100) : source.putpixel((x, y), couleur) ##------ Programme principal ------## ##----- Informations sur l'image -----## largeur = 100 # largeur de l'image, en pixels hauteur = 700 # hauteur de l'image, en pixels encodage = 'RGB' ##----- Conception de la nouvelle image -----## im = Image.new(encodage, (largeur, hauteur) ) carre(im, 0, (0, 0, 0) ) carre(im, 1, (255, 0, 0) ) carre(im, 2, (0, 255, 0) ) carre(im, 3, (255, 255, 0) ) carre(im, 4, (0, 0, 255) ) carre(im, 5, (255, 0, 255) ) carre(im, 6, (0, 255, 255) ) im.save('Carres_Empiles.jpg') im.show()
Une variante
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
##----- Importation des Modules -----## from PIL import Image # Ne pas oublier de l'importer pour un programme indépendant ##------ Définition des Fonctions ------## def carre(source, h, couleur): """ source – Image h - int, ordonnée (numéro du carré - de 0 à 6) couleur – tuple, triplet RGB Sortie : None – Ajoute à l'image source un carré de 100 pixels de couleur, à partir de l'ordonnée h. """ for x in range(100) : for y in range(h*100, (h+1)*100) : source.putpixel((x, y), couleur) ##------ Programme principal ------## ##----- Informations sur l'image -----## largeur = 100 # largeur de l'image, en pixels hauteur = 700 # hauteur de l'image, en pixels encodage = 'RGB' ##----- Conception de la nouvelle image -----## im = Image.new(encodage, (largeur, hauteur) ) h = 0 for i in range(2): for j in range(2): for k in range(2): if not(i == j == k == 1): carre(im, h, (255*k, 255*j, 255*i)) h += 1 im.save('Carres_Empiles.jpg') im.show()