Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import ctypes
- import tkinter.filedialog
- import matplotlib.pyplot
- import numpy
- import skimage.io
- import sklearn.decomposition
- ROOT = tkinter.Tk()
- FILEPATH = tkinter.filedialog.askopenfilename(title="Ouvrir une image",
- filetypes=[('Fichier tiff', '.tif')])
- # Choix par l'utilisateur de l'image .tif à utiliser, emplacer stocké dans la variable FILEPATH
- ROOT.withdraw()
- IMAGE = skimage.io.imread(FILEPATH)
- # Conversion de l'image du format TIF au format matriciel (modifiable par Python)
- NBR_PIXEL_Y = numpy.size(IMAGE, 0)
- NBR_PIXEL_X = numpy.size(IMAGE, 1)
- NBR_CANAUX = numpy.size(IMAGE, 2)
- # Calcul des constantes relatives à l'image sélectionnée (Nombre de pixels et de canaux)
- if NBR_CANAUX > NBR_PIXEL_Y: # Erreur dans le calcul précédent du au format des images Landsat
- NBR_CANAUX = numpy.size(IMAGE, 0)
- NBR_PIXEL_Y = numpy.size(IMAGE, 1)
- NBR_PIXEL_X = numpy.size(IMAGE, 2)
- MATRICE = numpy.zeros((NBR_PIXEL_Y, NBR_PIXEL_X, NBR_CANAUX), float)
- for INDEX in range(NBR_CANAUX):
- MATRICE[:, :, INDEX] = IMAGE[INDEX, :, :]
- # D'ou modification de l'ordre des constantes si nécessaire + Génération de MATRICE
- else:
- MATRICE = IMAGE.copy()
- # Sinon MATRICE vaut tout simplement l'image matricielle
- print("Matrice des observations")
- MATRICE_TRANSITION = numpy.reshape(MATRICE[:, :, 0], (1, NBR_PIXEL_Y * NBR_PIXEL_X))
- # Le premier canal de MATRICE est maintenant un vecteur ligne.
- for INDEX in range(1, NBR_CANAUX):
- MATRICE_TRANSITION = numpy.concatenate(
- (MATRICE_TRANSITION, numpy.reshape(MATRICE[:, :, INDEX], (1, NBR_PIXEL_Y * NBR_PIXEL_X))), axis=0)
- MATRICE = MATRICE_TRANSITION
- # MATRICE est maintenance une matrice de 3 à x lignes avec un nombre de colonnes
- # égal au nombre de pixels dans chacune des canaux composant l'image TIF
- print(MATRICE, "\n")
- NOMBRE_DONNES = numpy.shape(MATRICE)[1]
- print("Nombre de données : " + str(NOMBRE_DONNES) + "\n")
- # nombre de pixels dans chacune des canaux composant l'image TIF
- MOYENNE = numpy.mean(MATRICE, axis=1)
- print("Moyenne des observations")
- print(MOYENNE, "\n")
- # Vecteur ligne donnant la vecteur de pixel moyen de chacune des canaux de l'image TIF
- # Format : Nombre de lignes
- MOYENNE = numpy.reshape(MOYENNE, (len(MOYENNE), 1))
- MATRICE_CENTREE = MATRICE - MOYENNE
- print("Matrice centrée des observations")
- print(MATRICE_CENTREE, "\n")
- # Soustration sur chacune des ligne de la moyenne des lignes
- # Format : Le même que MATRICE
- MATRICE_COVARIANCE = (1.0 / (NOMBRE_DONNES - 1)) * numpy.dot(MATRICE_CENTREE, MATRICE_CENTREE.transpose())
- print("Matrice de covariance des observations")
- print(MATRICE_COVARIANCE, "\n")
- # Calcul de la matrice de covariance des données
- # Format : Nombre de canaux * Nombre de canaux
- MATRICE_A = (1. / numpy.sqrt(float(NOMBRE_DONNES) - 1)) * MATRICE_CENTREE.transpose()
- print("Matrice A")
- print(MATRICE_A, "\n")
- # Matrice centrée multiplié par la racine carrée du nombre de pixels dans chaque couche ...
- # Format : Le même que MATRICE
- # import numpy.linalg
- # U, SM, VT = numpy.linalg.svd(MATRICE_A)
- # Calcul de la décomposition en valeur singulière
- # sauf que les valeurs sont codés sur 4 bits et que j'ai que 16Go de ram et
- # qu'ils m'en faudrait une bonne centaine donc "MemoryError"^^
- ACP = sklearn.decomposition.PCA(n_components=3)
- ACP.fit(MATRICE_A)
- # https://github.com/scikit-learn/scikit-learn/blob/a24c8b46/sklearn/decomposition/pca.py#L313
- # La même chose que le SVD mais on appelle ca le PCA
- # Principal Component Analysis
- # http://scikit-learn.org/stable/modules/generated/sklearn.decomposition.PCA.html
- print("\n", "Q1 : Composantes principales")
- COMPOSANTE_PRINCIPALES = ACP.components_
- print(COMPOSANTE_PRINCIPALES)
- print("\n", "Écarts-types associés")
- VARIANCE = ACP.explained_variance_ratio_
- print(VARIANCE ** 0.5)
- print("\n", "Q2 : Variance totale :")
- print(numpy.sum(VARIANCE))
- print("\n", "Q3 : Pourcentage de variance totale :")
- # ACP est une grande librarie dans laquelle on vient récupérer
- # les données qui nous interresse : Variance, Composantes principales...
- TRANSFORMATION = transformation = numpy.dot(MATRICE_A, COMPOSANTE_PRINCIPALES.T)
- # https://github.com/scikit-learn/scikit-learn/blob/a24c8b46/sklearn/decomposition/pca.py#L332
- # TRANSFORMATION a 3 colonnes et le même nombre de lignes que MATRICE
- """ def transform(self, X):
- Apply dimensionality reduction to X.
- X is projected on the first principal components previously extracted
- from a training set.
- #-----------------------------------------------------------------------------
- check_is_fitted(self, ['mean_', 'components_'], all_or_any=all)
- X = check_array(X)
- if self.mean_ is not None:
- X = X - self.mean_
- X_transformed = np.dot(X, self.components_.T)
- if self.whiten:
- X_transformed /= np.sqrt(self.explained_variance_)
- return X_transformed
- """
- DPI = 100
- FIGURE = matplotlib.pyplot.figure()
- # On prépare la répresentation graphique de notre ACP
- for INDEX, VALUE in enumerate(VARIANCE):
- TRANSFORMATION[:, INDEX] += -numpy.min(TRANSFORMATION[:, INDEX])
- TRANSFORMATION[:, INDEX] *= (255 / numpy.max(TRANSFORMATION[:, INDEX]))
- # On prend une matrice dont on ramène la valeur minimale à 0 et la maximale à 255
- # Toutes les valeurs sont modifiées pour améliorer le contraste !
- MATRICE = numpy.reshape(TRANSFORMATION[:, (INDEX)], (NBR_PIXEL_Y, NBR_PIXEL_X))
- IMAGE = numpy.zeros((NBR_PIXEL_Y, NBR_PIXEL_X, 3), dtype=numpy.uint8)
- IMAGE[:, :, 0] = MATRICE
- IMAGE[:, :, 1] = MATRICE
- IMAGE[:, :, 2] = MATRICE
- # Affichage d'une image possédant 3 canaux identiques : Image en nuances de gris.
- place = int('13' + str(INDEX+1))
- matplotlib.pyplot.subplot(place)
- # 131/132/133 => 1 lignes,3 colonnes,3 images différentes
- skimage.io.imshow(IMAGE)
- # Equivalent de plt.plot pour une image
- pourcentage = str(round(VARIANCE[INDEX] / numpy.sum(VARIANCE) * 100, 2))
- # Calcul du pourcentage de chacune des composantes
- print("Composante", INDEX+1, "=", pourcentage, " %")
- titre = "Composante principale " + str(INDEX+1) + " : " + pourcentage + "%"
- matplotlib.pyplot.title(titre)
- matplotlib.pyplot.axis('off')
- # On supprime les axes parce que ce sont des images et pas des graphiques
- USER_INFORMATIONS = ctypes.windll.user32
- FIGURE.set_size_inches((USER_INFORMATIONS.GetSystemMetrics(0) / DPI,
- 0.8 * USER_INFORMATIONS.GetSystemMetrics(1) / DPI))
- # On optimise la taille de l'image afin qu'elle soit juste à la taille de l'écran en largeur
- FIGURE.set_tight_layout(True)
- # On optimise l'image en faisant en sorte que rien ne se superpose
- NOM_SAVE = str(str(FILEPATH).split("/")[-1]).split(".")[0] + '_ACP.png'
- # On nomme le fichier de facon intelligente
- matplotlib.pyplot.savefig(NOM_SAVE, bbox_inches='tight', dpi=DPI)
- # On sauvegarde l'image en supprimant les espaces blancs inutiles sur les cotés
- matplotlib.pyplot.show()
- # On affiche l'image sans axe dans une fenêtre adaptée en largeur
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement