merci à Wikipedia et à stackoverflow
le but de ce TP n’est pas d’apprendre le traitement d’image
on se sert d’images pour égayer des exercices avec numpy
(et parce que quand on se trompe ça se voit)
import numpy as np
from matplotlib import pyplot as plt
Création d’un patchwork¶
- Le fichier
data/rgb-codes.txt
contient une table de couleurs:
AliceBlue 240 248 255
AntiqueWhite 250 235 215
Aqua 0 255 255
.../...
YellowGreen 154 205 50
Le nom de la couleur est suivi des 3 valeurs de ses codes R
, G
et B
Lisez cette table en Python
et rangez-la dans la structure qui vous semble adéquate.
# votre code
- Affichez, à partir de votre structure, les valeurs rgb entières des couleurs suivantes
'Red'
,'Lime'
,'Blue'
# votre code
Faites une fonction
patchwork
qui prend deux paramètres obligatoires:- une liste de couleurs
- et la structure donnant le code des couleurs RGB qu’on a obtenue à l’étape 1
et retourne un tableaunumpy
avec un patchwork de ces couleurs
Testez votre fonction en affichant le résultat obtenu sur un jeu de couleurs fourni
indices
- sont potentiellement utiles pour cet exo:
- la fonction
np.indices()
- l’indexation d’un tableau par un tableau
- la fonction
- aussi, ça peut être habile de couper le problème en deux, et de commencer par écrire une fonction
rectangle_size(n)
qui vous donne la taille du patchwork en fonction du nombre de couleurset pour calculer la taille au plus justeen version un peu brute, on pourrait utiliser juste la racine carrée; par exemple avec 5 couleurs créer un carré 3x3 - mais 3x2 c’est quand même mieux !
voici pour vous aider à calculer le rectangle qui contient n couleurs
n rect n rect n rect n rect 1 1x1 5 2x3 9 3x3 14 4x4 2 1x2 6 2x3 10 3x4 15 4x4 3 2x2 7 3x3 11 3x4 16 4x4 4 2x2 8 3x3 12 3x4 17 4x5
# votre code
def rectangle_size(n):
"""
return a tuple lines, cols for
the smallest rectangle that contains n cells
"""
...
# votre code
def patchwork(colors, colormap, side=10):
"""
"""
...
- Tirez aléatoirement une liste de couleurs et appliquez votre fonction à ces couleurs.
# votre code
- Sélectionnez toutes les couleurs à base de blanc et affichez leur patchwork
même chose pour des jaunes
# votre code
- Appliquez la fonction à toutes les couleurs du fichier
et sauver ce patchwork dans le fichierpatchwork.png
avecplt.imsave
# votre code
- Relisez et affichez votre fichier
attention si votre image vous semble floue c’est juste que l’affichage grossit vos pixels
vous devriez obtenir quelque chose comme ceci

# votre code
Somme dans une image & overflow¶
- Lisez l’image
data/les-mines.jpg
# votre code
- Créez un nouveau tableau
numpy.ndarray
en sommant avec l’opérateur+
les valeurs RGB des pixels de votre image
# votre code
Regardez le type de cette image-somme, et son maximum; que remarquez-vous?
Affichez cette image-somme; comme elle ne contient qu’un canal il est habile de l’afficher en “niveaux de gris” (normalement le résultat n’est pas terrible ...)niveaux de gris ?cherchez sur google
pyplot imshow cmap gray
# votre code
- Créez un nouveau tableau
numpy.ndarray
en sommant mais cette fois avec la fonction d’agrégationnp.sum
les valeurs RGB des pixels de votre image
# votre code
- Comme dans le 2., regardez son maximum et son type, et affichez la
# votre code
- Les deux images sont de qualité très différente, pourquoi cette différence ? Utilisez le help
np.sum?
# votre code / explication
- Passez l’image en niveaux de gris de type entiers non-signés 8 bits
(de la manière que vous préférez)
# votre code
- Remplacez dans l’image en niveaux de gris,
les valeurs >= à 127 par 255 et celles inférieures par 0
Affichez l’image avec une carte des couleurs des niveaux de gris
vous pouvez utilisez la fonctionnumpy.where
# votre code
- avec la fonction
numpy.unique
regardez les valeurs différentes que vous avez dans votre image en noir et blanc
# votre code
Image en sépia¶
Pour passer en sépia les valeurs R, G et B d’un pixel
(encodées ici sur un entier non-signé 8 bits)
- on transforme les valeurs
R
,G
etB
par la transformation0.393 * R + 0.769 * G + 0.189 * B
0.349 * R + 0.686 * G + 0.168 * B
0.272 * R + 0.534 * G + 0.131 * B
(attention les calculs doivent se faire en flottants pas en uint8
pour ne pas avoir, par exemple, 256 devenant 0) - puis on seuille les valeurs qui sont plus grandes que
255
à255
- naturellement l’image doit être ensuite remise dans un format correct
(uint8 ou float entre 0 et 1)
# exemple de produit de matrices avec `numpy.dot`
# le help(np.dot) dit: dot(A, B)[i,j,k,m] = sum(A[i,j,:] * B[k,:,m])
i, j, k, m, n = 2, 3, 4, 5, 6
A = np.arange(i*j*k).reshape(i, j, k)
B = np.arange(m*k*n).reshape(m, k, n)
C = A.dot(B)
# or C = np.dot(A, B)
print(f"en partant des dimensions {A.shape} et {B.shape}")
print(f"on obtient un résultat de dimension {C.shape}")
print(f"et le nombre de termes dans chaque `sum()` est {A.shape[-1]} == {B.shape[-2]}")
en partant des dimensions (2, 3, 4) et (5, 4, 6)
on obtient un résultat de dimension (2, 3, 5, 6)
et le nombre de termes dans chaque `sum()` est 4 == 4
Exercice
- Faites une fonction qui prend en argument une image RGB et rend une image RGB sépia
la fonctionnumpy.dot
peut être utilisée si besoin, voir l’exemple ci-dessus
# votre code
- Passez votre patchwork de couleurs en sépia
Lisez le fichierpatchwork-all.jpg
si vous n’avez pas de fichier perso
# votre code
- Passez l’image
data/les-mines.jpg
en sépia
# votre code
Exemple de qualité de compression¶
- Importez la librairie
Image
dePIL
(pillow)
(vous devez peut être installer PIL dans votre environnement)
# votre code
- Quelle est la taille du fichier
data/les-mines.jpg
sur disque ?
file = "data/les-mines.jpg"
# votre code
- Lisez le fichier ‘data/les-mines.jpg’ avec
Image.open
et avecplt.imread
# votre code
- Vérifiez que les valeurs contenues dans les deux objets sont proches
# votre code
- Sauvez (toujours avec de nouveaux noms de fichiers)
l’image lue parimread
avecplt.imsave
l’image lue parImage.open
avecsave
et unequality=100
(save
s’applique à l’objet créé parImage.open
)
# votre code
- Quelles sont les tailles de ces deux fichiers sur votre disque ?
Que constatez-vous ?
# votre code
- Relisez les deux fichiers créés et affichez avec
plt.imshow
leur différence
# votre code