Licence CC BY-NC-ND, Valérie Roy & Thierry Parmentelat

à télécharger

pour réaliser ce TP localement sur votre ordi, commencez par télécharger le zip

TP images (1/2)#

merci à Wikipedia et à stackoverflow

disclaimer

vous n’allez pas faire ici de traitement d’image - on se sert d’images pour égayer des exercices avec numpy
(et parce que quand on se trompe: on le voit)

Notions intervenant dans ce TP

  • création, indexation, slicing, modification de numpy.ndarray

  • affichage d’image (RBG, RGB-A, niveaux de gris)

  • lecture de fichier jpg

  • les autres notions utilisées sont rappelées (très succinctement)

N’oubliez pas d’utiliser le help en cas de problème.

import des librairies#

  1. Importez la librairie numpy

  2. Importez la librairie matplotlib.pyplot
    ou toute autre librairie d’affichage que vous aimez et/ou savez utiliser: seaborn

# votre code
  1. optionnel - changez la taille par défaut des figures matplotlib par exemple choisissez d’afficher les figures dans un carré de 4x4 (en théorie ce sont des inches)

    Tip

    il y a plein de façons de le faire, google et/ou stackoverflow sont vos amis…

création d’une image de couleur#

Rappels (rapides)

  • dans une image en couleur, les pixels sont représentés par leurs dosages dans les 3 couleurs primaires: red, green, blue (RGB)

    ../../_images/synthese-additive1.png
  • l’affichage à l’écran, d’une image couleur rgb, utilise les règles de la synthèse additive
    (r, g, b) = (255, 255, 255) donne la couleur blanche
    (r, g, b) = (0, 0, 0) donne du noir
    (r, g, b) = (255, 0, 0) donne du rouge (r, g, b) = (255, 255, 0) donne du jaune …

  • pour afficher le tableau im comme une image, utilisez: plt.imshow(im)

  • pour afficher plusieurs images dans une même cellule de notebook faire plt.show() après chaque plt.imshow(...)

Exercice

  1. Créez un tableau non initialisé, pour représenter une image carrée de 91 pixels de côté, d’entiers 8 bits non-signés, et affichez-le

    indices

    • il vous faut pouvoir stocker 3 uint8 par pixel pour ranger les 3 couleurs

    • on s’intéresse uniquement à la taille, et pas au contenu puisqu’on a dit “non initialisé”; que vous ayez du blanc, du noir ou du bruit, c’est OK

# votre code
  1. Transformez le en tableau blanc (en un seul slicing) et affichez-le

# votre code
  1. Transformez le en tableau vert (en un seul slicing) et affichez-le

# votre code
  1. Affichez les valeurs RGB du premier pixel de l’image, et du dernier

# votre code
  1. Faites un quadrillage d’une ligne bleue, toutes les 10 lignes et colonnes et affichez-le

# votre code

lecture d’une image en couleur#

  1. Avec la fonction plt.imread lisez le fichier data/les-mines.jpg

# votre code
  1. Vérifiez si l’objet est modifiable avec im.flags.writeable; si il ne l’est pas, copiez l’image

# votre code
  1. Affichez l’image

# votre code
  1. Quel est le type de l’objet créé ?

# votre code
  1. Quelle est la dimension de l’image ?

  1. Quelle est la taille de l’image en hauteur et largeur ?

# votre code
  1. Quel est le nombre d’octets utilisé par pixel ?

  1. Quel est le type des pixels ?
    (deux types pour les pixels: entiers non-signés 8 bits ou flottants sur 64 bits)

# votre code
  1. Quelles sont ses valeurs maximale et minimale des pixels ?

# votre code
  1. Affichez le rectangle de 10 x 10 pixels en haut de l’image

# votre code

accès à des parties d’image#

  1. Relire l’image

# votre code
  1. Slicer et afficher l’image en ne gardant qu’une ligne et qu’une colonne sur 2, 5, 10 et 20
    (ne dupliquez pas le code)

indices

  • vous pouvez créer plusieurs figures depuis une seule cellule
    pour cela, faites plusieurs fois la séquence plt.imshow(...); plt.show()

  • vous pouvez ensuite choisir de ‘replier’ ou non la zone output en hauteur;
    c’est-à-dire d’afficher soit toute la hauteur, soit une zone de taille fixe avec une scrollbar pour naviguer
    pour cela cliquez dans la marge gauche de la zone output

# votre code
  1. Isoler le rectangle de l lignes et c colonnes en milieu d’image
    affichez-le pour (l, c) = (10, 20)) puis (l, c) = (100, 200)

# votre code

canaux RGB de l’image#

  1. Relire l’image

# votre code
  1. Découpez l’image en ses trois canaux Red, Green et Blue (Il s’agit donc de construire trois tableaux de dimension 2)

# votre code
  1. Afficher chaque canal avec plt.imshow; la couleur est-elle la couleur attendue ?
    Si oui très bien, si non que se passe-t-il ?

    rappel table des couleurs

    • RGB représente directement l’encodage de la couleur du pixel, et non un indice dans une table

    • donc pour afficher des pixel avec les 3 valeurs RGB pas besoin de tables de couleurs, on a la couleur

    • mais pour afficher une image unidimensionnelle contenant des nombres de 0 à 255, il faut bien lui dire à quoi correspondent les valeurs
      (lors de l’affichage, le 255 des rouges n’est pas le même 255 des verts)

    • du coup, voyez le paramètre cmap= de plt.imshow; et notamment avec 'Reds', 'Greens' ou 'Blues'

# votre code
  1. Corrigez vos affichages si besoin

# votre code
  1. Copiez l’image, et dans la copie, remplacer le carré de taille (200, 200) en bas à droite:

    • d’abord par un carré de couleur RGB (219, 112, 147) (vous obtenez quelle couleur)

    • puis par un carré blanc avec des rayures horizontales rouges de 1 pixel d’épaisseur

# votre code
  1. enfin pour vérifier, affichez les 20 dernières lignes et colonnes du carré à rayures

# votre code

transparence des images#

rappel: la transparence

rappel RGB-A

  • on peut indiquer, dans une quatrième valeur des pixels, leur transparence

  • ce 4-ème canal s’appelle le canal alpha

  • les valeurs vont de 0 pour transparent à 255 pour opaque

  1. Relire l’image initiale (sans la copier)

# votre code
  1. Créez un tableau vide de la même hauteur et largeur que l’image, du type de l’image initiale, mais avec un quatrième canal

# votre code
  1. Copiez-y l’image initiale, mettez le quatrième canal à 128 et affichez l’image

# votre code

image en niveaux de gris en float#

  1. Relire l’image data/les-mines.jpg

# votre code
  1. Passez ses valeurs en flottants entre 0 et 1 et affichez-la

# votre code
  1. Transformer l’image en deux images en niveaux de gris :
    a. en mettant pour chaque pixel la moyenne de ses valeurs R, G, B
    b. en utilisant la correction Y (qui corrige le constrate) basée sur la formule
    G = 0.299 * R + 0.587 * V + 0.114 * B c. optionnel: si vous pensez à plusieurs façons de faire la question a., utilisez %%timeit pour les benchmarker et choisir la plus rapide

# votre code
  1. Prenez l’image de 3.a (moyenne des 3 canaux), passez les pixels au carré, et affichez le résultat Quel est l’effet sur l’image ?

# votre code
  1. Pareil, mais cette fois utilisez la racine carrée; quel effet cette fois ?

# votre code
  1. Convertissez l’image (de 3.a toujours) en type entier, et affichez la

# votre code

affichage grille de figures#

Mettre plusieurs figures dans une grille

Mettons l’exercice sur pause pour l’instant, et voyons comment avec matplotlib, on peut mettre faire une figure composite, i.e. qui contienne plusieurs figures disposés dans une grille

0) on dessine toujours la même chose, juste avec des couleurs différentes

# pas important, juste un exemple de truc à dessiner

X = np.linspace(0, 2*np.pi, 50)
Y = np.sin(X)

1) on créé une figure globale et des sous-figures

les sous-figures sont appelées axes par convention matplotlib
on construit notre grille ici de 2 lignes et 3 colonnes

# ici axes va être un tableau numpy de shape .. (2, 3)
fig, axes = plt.subplots(2, 3)

les cases pour les sous-figures sont ici dans la variable axes
qui est un numpy.ndarray de taille 2 lignes et 3 colonnes

2) on affiche des sous-figure dans des cases de la grille

# en haut à gauche
axes[0, 0].plot(X, Y, 'b')
axes[0, 1].plot(X, Y, 'r')
# en haut à droite
axes[0, 2].plot(X, Y, 'y')
axes[1, 0].plot(X, Y, 'k')
axes[1, 1].plot(X, Y, 'g')
axes[1, 2].plot(X, Y, 'm')
# ce qui nous donne, mis bout à bout
import numpy as np
import matplotlib.pyplot as plt

X = np.linspace(0, 2*np.pi, 50)
Y = np.sin(X)

# le code
fig, axes = plt.subplots(2, 3)
print(f"{type(axes)=}")
print(f"{axes.shape=}")

axes[0, 0].plot(X, Y, 'b')
# axes[0, 1].plot(X, Y, 'r')
axes[0, 2].plot(X, Y, 'y')
axes[1, 0].plot(X, Y, 'k')
axes[1, 1].plot(X, Y, 'g')
axes[1, 2].plot(X, Y, 'm')

fig.suptitle("sinus en couleur", fontsize=20)
axes[0, 0].set_title('sinus bleu')
axes[0, 2].set_xlabel('de 0 à 2 pi')
axes[1, 1].set_ylabel('de -1 à 1')
axes[1, 2].set_title('sinus magenta')
plt.tight_layout();
type(axes)=<class 'numpy.ndarray'>
axes.shape=(2, 3)
../../_images/99501e4c789471ce2b90ec5d97a3f7cb625c7d54587c946a6db082dccfd0970d.png

reprenons le TP#

exercice

Reprenez les trois images en niveau de gris que vous aviez produites ci-dessus:
A: celle obtenue avec la moyenne des rgb
B: celle obtenue avec la correction Y
C: celle obtenue avec la racine carrée

  1. Affichez les trois images côte à côte

    A B C
    
# votre code
  1. Affichez-les en damier:

    A B C
    C A B
    B C A
    
# votre code