In [ ]:
#chgt de dossier
import os
os.chdir("C:/Users/ricco/Desktop/demo")

# lecture de l'image
from PIL import Image
image = Image.open('Benzecri.jpg')

#affichage de l'image
import matplotlib.pyplot as plt
plt.imshow(image)
Out[ ]:
<matplotlib.image.AxesImage at 0x1e81cbf99a0>
In [ ]:
#type de l'objet image
type(image)
Out[ ]:
PIL.JpegImagePlugin.JpegImageFile
In [ ]:
#tranformation de l'image en tableau numpy
import numpy
image = numpy.asarray(image)

#vérif.
type(image)
Out[ ]:
numpy.ndarray
In [ ]:
#dimension de l'image (tableau)
#en pixel : nb de lignes x nb de colonnes x 3 composantes (RGB)
image.shape
Out[ ]:
(587, 788, 3)
In [ ]:
#taille en octets
image.size
Out[ ]:
1387668
In [ ]:
#redimensionner l'image en matrice 2D
#chaque ligne = 1 pixel avec 3 valeurs (couleurs RGB)
pixel_vals = image.reshape((-1,3))

#nouvelle dimension -> matrice classique en Machine Learning
pixel_vals.shape
Out[ ]:
(462556, 3)
In [ ]:
#comparaison - premier point de l'image
print(image[0,0,:])

#avec
print(pixel_vals[0,:])
[28 37 46]
[28 37 46]
In [ ]:
#comparaison - dernier point de l'image
print(image[-1,-1,:])

#avec
print(pixel_vals[-1,:])
[255 255 255]
[255 255 255]
In [ ]:
#conversion en matrice de valeurs réelles
pixel_vals = numpy.float32(pixel_vals)

#10 premiers pixels
pixel_vals[:10,:]
Out[ ]:
array([[28., 37., 46.],
       [28., 37., 46.],
       [29., 38., 45.],
       [32., 41., 48.],
       [37., 44., 50.],
       [40., 47., 53.],
       [43., 48., 52.],
       [43., 48., 52.],
       [38., 42., 45.],
       [40., 44., 47.]], dtype=float32)
In [ ]:
#méthode K-Means de scipy
from scipy.cluster.vq import kmeans

#nombre de clusters
k = 2

#instanciation et entraînement
#equiv. du fit()
codebooks, distortion = kmeans(obs = pixel_vals, k_or_guess = k, seed = 0)
In [ ]:
#pas de WSS fourni, à la place
#moyenne de la distance des points
#à leurs centroïdes
distortion
Out[ ]:
35.871216
In [ ]:
#centroïdes -- couleurs représentatives
codebooks
Out[ ]:
array([[211.02675, 201.8653 , 190.02257],
       [ 66.87859,  85.57478,  84.91747]], dtype=float32)
In [ ]:
#labels --> associé à chaque pixel son cluster d'appartenance
#en utilisant la distance aux centroïdes (codebooks)
#equiv. du predict() [inference]
from scipy.cluster.vq import vq
labels, _ = vq(pixel_vals,codebooks)

#dim.
labels.shape
Out[ ]:
(462556,)
In [ ]:
#effectifs des clusters
#c.-à-d. nb de pixels associés à chaque cluster
numpy.unique(labels,return_counts=True)
Out[ ]:
(array([0, 1]), array([ 92786, 369770], dtype=int64))
In [ ]:
#convertir les valeurs codebooks en entiers
centers = numpy.uint8(codebooks)
centers
Out[ ]:
array([[211, 201, 190],
       [ 66,  85,  84]], dtype=uint8)
In [ ]:
#recomposer l'image avec les "k" couleurs
#c.-à-d. à chaque pixel, on remplace sa couleur
#par la couleur du codebook qui lui est associé
segmented_data = centers[labels]

#verif.
segmented_data.shape
Out[ ]:
(462556, 3)
In [ ]:
#verif. de l'image
segmented_data[:10,:]
Out[ ]:
array([[66, 85, 84],
       [66, 85, 84],
       [66, 85, 84],
       [66, 85, 84],
       [66, 85, 84],
       [66, 85, 84],
       [66, 85, 84],
       [66, 85, 84],
       [66, 85, 84],
       [66, 85, 84]], dtype=uint8)
In [ ]:
#verif. bis -- l'image n'est composée que de ces "k" couleurs
numpy.unique(segmented_data[:,:],axis=0)
Out[ ]:
array([[ 66,  85,  84],
       [211, 201, 190]], dtype=uint8)
In [ ]:
#reshape l'image dans les dimensions originelles
segmented_image = segmented_data.reshape(image.shape)

#affichage
plt.imshow(segmented_image)
Out[ ]:
<matplotlib.image.AxesImage at 0x1e81e366910>