Plan 256 shades of grey -

publicité
Plan
256 shades of grey
1
Du pixel au fichier
Pixels
Formats de fichiers image
2
Manipulations avec Python
Trois niveaux d’abstraction
Du fichier aux pixels
Des pixels au fichier
Un peu de technique
3
Quelques traitements d’image
Gestion du contraste
Éclaircissement
Floutage
Détection de contours
[email protected] - http://blog.psi945.fr
Lundi 9 janvier 2017
Stéphane Gonnord
256 shades of grey
Année 2016/2017
1 / 16
Qu’est-ce qu’une image ?
Stéphane Gonnord
256 shades of grey
Année 2016/2017
2 / 16
Quelques formats d’image
À l’écran/sur le papier : un rectangle/une matrice de pixels
(PICture ELements).
Chat : image 2048 × 1536 pixels ; poids en kilo-octets.
Un pixel = nuance de gris (...) entre 0 et 255... ou entre 0 et 1.
Ou bien (RGB) : trois niveaux Red/Green/Blue de 0 à 255.
Stockage dans un fichier :
�
�
pixel par pixel...
ou par compression d’une image initiale.
Compression : destructive ou non (avec ou sans perte
d’information).
Poids d’un fichier BitMaP (pixel par pixel sans compression) en
RGB :
3 × L × H octets ;
trois fois moins en noir et blanc !
Stéphane Gonnord
256 shades of grey
Année 2016/2017
3 / 16
Ext.
destr.
compr.
chat (RGB)
chat (N&B)
bmp
png
gif
jpg
NON
NON
NON
OUI
NON
OUI
OUI
OUI
9437
4999
3336
400
3147
1533
3367
366
Stéphane Gonnord
256 shades of grey
Année 2016/2017
4 / 16
Trois niveaux d’abstraction (via PIL)
Du fichier aux pixels
Le fichier, support « physique », sur le disque.
Image.open : objet image à partir du fichier.
L’objet Python « image » intermédiaire. Contient les informations
sur l’encodage... et les données.
numpy.array : tableau/matrice de pixels à partir de l’objet image.
La matrice des pixels.
Définition de l’objet et de la matrice
>>> chat = im.open(’images_out/baroudeurBW.jpg’)
>>> pixels_chat = np.array(chat)
Fichier
Objet Python
Matrice de pixels
’baroudeur.bmp’
<PIL.BmpImage...
...
image mode=RGB
...>
<PIL.JpegImage...
...
image mode=RGB
...>
<PIL.JpegImage...
...
image mode=L
...>
array([[[ 12, 16, 25],
...
[80, 86, 60]]],
dtype=uint8)
array([[[ 12, 16, 25],
...
[80, 86, 60]]],
dtype=uint8)
array([[14, 15, 15, ...,
...
... 80, 80, 80]],
dtype=uint8)
’baroudeur.jpg’
’baroudeurBW.jpg’
Stéphane Gonnord
256 shades of grey
Exemple :
Année 2016/2017
Résultat
>>> chat
<PIL.JpegImagePlugin.JpegImageFile image mode=L
size=2048x1536 at 0xB5F911AC>
>>> pixels_chat
array([[ 14, 15, 15, ..., 208, 212, 215],
[ 14, 15, 15, ..., 211, 212, 214],
...,
[208, 206, 203, ..., 80, 80, 80]], dtype=uint8)
5 / 16
Des pixels au fichier
Stéphane Gonnord
256 shades of grey
Année 2016/2017
6 / 16
Quelques points techniques
Slicing : tableau[ a:b , c:d ] en lecture ou écriture.
numpy.zeros( (a,b) ) et numpy.ones( (a,b) ) attention aux types.
Conversion en niveaux (Levels) de gris :
Image.fromarray : des pixels à l’objet image.
Méthode save des objets image : pour sauver sous différents formats.
Exemple :
image.open(’image_couleur.jpg’).convert(’L’).save(’image_BW.png’)
Que fais-je ?
Appliquer une fonction aux pixels : deux approches
pixels_chat = np.array( im.open(’baroudeurBW.jpg’) )
Appliquons f à M :
pixels_chat[ 100:200 , 500:1500 ] =
255*np.ones((100, 1000),dtype=’uint8’)
pixels1 = np.array(im.open(’baroudeur.jpg’))
im.fromarray(pixels_chat).save(’mystere.jpg’)
(H, L, _) = pixels1.shape # hauteur * largeur * 3
pixels2 = np.copy(pixels1)
Pixel par pixel ; 48 secondes
for i in range( H ):
for j in range( L ):
pixels2[i][j] = contraste( pixels2[i][j] )
Par application d’une fonction « vectorisée » au tableau ; 3 secondes
contraste_vecto = np.vectorize( contraste )
pixels2 = contraste_vecto( pixels1 )
# en fait : pixels2 = np.array( ... , dtype=’uint8’)
im.fromarray(pixels2).save(’baroudeurBW2.jpg’)
Stéphane Gonnord
256 shades of grey
Année 2016/2017
7 / 16
Stéphane Gonnord
256 shades of grey
Année 2016/2017
8 / 16
Fonction de contraste
Que devient le chat ?
On applique f : {0, 1, ..., 255} → {0, 1, ..., 255} à chaque pixel.
Pour contraster/décontraster :
f1 (x ) = 128 + 2 × (x − 128)
f2 (x ) = 128 + (x − 128)/2
On revient à {0, 1, ..., 255} en cas de dépassement !
���
� � �� ���
� � �� ���
�
���
���
��
�
�
Stéphane Gonnord
��
���
�
256 shades of grey
���
���
Année 2016/2017
9 / 16
Un goutte contrastée 5 fois
Stéphane Gonnord
256 shades of grey
Stéphane Gonnord
256 shades of grey
Année 2016/2017
10 / 16
Année 2016/2017
12 / 16
Un autre, aux bords moins nets
Année 2016/2017
11 / 16
Stéphane Gonnord
256 shades of grey
Floutons πR 2 !
Éclaircissement ou assombrissement
Fonction pour éclaircir/assombrir :
f3 (x ) = 255 − (255 − x )/2
���
Mi ,j ←
f4 (x ) = x /2
1
9
(Mi −1,j −1 + · · · + Mi +1,j +1 )
� � �� ���
� � �� ���
�
���
���
��
�
�
Stéphane Gonnord
��
���
�
���
���
256 shades of grey
Année 2016/2017
13 / 16
Stéphane Gonnord
Détection de contours
C’est fini !
On noircit les pixels (i , j ) tels que :
Merci de votre attention
256 shades of grey
Année 2016/2017
14 / 16
256 shades of grey
Année 2016/2017
16 / 16
(Pi −1,j − Pi +1,j )2 + (Pi ,j −1 − Pi ,j +1 )2 > s,
avec un seuil... à fixer ! On contraste d’abord l’image
Stéphane Gonnord
256 shades of grey
Année 2016/2017
15 / 16
Stéphane Gonnord
Téléchargement