import imageio as iio import random as rd import numpy as np from math import * img = iio.imread( "G:\\Serpent.jpg") hauteur,longueur,colonne = img.shape img.reshape( hauteur*longueur, 3) # nouvelle vue de l'image comme un tableau à deux dimensions Npixels*3 nb_pixels=hauteur*longueur np.asarray(img) def initialisation(k,img): centroids_create = img.copy() # copie la matrice img pour ensuite créer une matrice aléatoire de kluster de même dimension que l'image np.random.shuffle(centroids_create) np.asarray(centroids_create[:k]) # cette fois-ci on convertit l'entrée en tableau et on affiche les k premières lignes de ce tableau de k clusters return(centroids_create,centroids_create.shape,centroids_create[:k]) def distanceeuclidienne(img, initialisation): pp=[] for i in img: norme=[] for j in initilisation: norme.append(m.sqrt((j[0]-i[0])**2+(j[1]-i[1])**2)+(j[2]-i[2])**2) pp.append(norme.index(min(normes))) return (np.asarray(pp)) def mouvement_centroids(img, distanceeuclidienne, initialisation ): for i in range (len(initialisation)): indices=np.where(distanceeuclidienne==i)[0] #tableau avec pour chaque case un indice sommerouge=0 sommevert=0 sommebleu=0 for j in indices: sommerouge=sommerouge+img[j][0] #(rouge) sommevert=sommevert+img[j][1] #(vert) sommebleu=sommebleu+img[j][2] #(bleu) card=len(indices) cent[i][0]=sommerouge//card cent[i][1]=sommevert//card cent[i][2]=sommebleu//card return(cent) # fonction affectant les nouvelles poisitions des centroides done = False def ite_mouvement_centro(img,initilisation): epsi = 0.0000000000000001 def ecart(copie, origin, index ): erouge = abs(distanceeuclidienne[index][0]-initialisation[index][0]) evert = abs(distanceeuclidienne[index][1]-initialisation[index][1]) ebleu = abs(distanceeuclidienne[index][2]-initialisation[index][2]) return(True if erouge<=epsi and evert<=epsi and ebleu<=epsi else False ) close_centroid=initilisation.copy pp=close_centroid(img,initialisation) initialisation=mouvement_centroids(img,pp,initilisation) for i in range (len(close_centroids)): if ecart(distanceeuclidienne,initialisation,i): if (i==(len(distanceeuclidienne)-1)): done=False else: pass else: break return centr def get_cmap(N): color_norm = colors.Normalize(vmin=0, vmax=N-1) scalar_map = cmx.ScalarMappable(norm=color_norm,cmap='hsv') def map_index_to_rgb_color(index): return scalar_map.to_rgba(index) return map_index_to_rgb_color #Fonction kmeans, est la fonction principale qui appelle toute les fonctions ci-dessus. Elle sort un array avec les #coordonnées de chaque centroide après que les centroides convergent et affiche dans une figure le grpahique de chaque #chaque points avant et après application de kmeans''' def kmeans(data, k): plt.subplot(121) centroids = init_centroids(data, k) cmap = get_cmap(k+1) ccentroids = close_centroid(data, centroids) for i in range(len(ccentroids)): plt.scatter(centroids[:,:, 0], centroids[:,:; 1],centroids[:,:; 2], s=20, c='black') plt.title('Avant mouvement des centroïdes') plt.grid(False) plt.axis('off') plt.subplot(122) centroids = ite_movmt_centro(data,centroids) ccentroids = close_centroid(data, centroids) for i in range(len(ccentroids) - 1): plt.scatter(data[i, 0], data[i, 1], c=cmap(ccentroids[i])) plt.scatter(centroids[:,:,0], centroids[:,:, 1], centroids[:,:,2] s=20, c='black') plt.title('Après mouvement des centroïdes') plt.grid(False) plt.axis('off') fig = plt.gcf() fig.canvas.set_window_title('Algorirthme K-Means') print("Coordonnée des centroides :") plt.show() return centroids #Fonction kmeans_rand appelle kmean avec des données aléatoire def kmeans_rand(min,max,n,k): return kmeans(np.random.randint(min, max, size=(n, 2)), k) #Fonction kmeans_file appelle kmean avec des données pris d'un fichier def kmeans_file(file_n,k): return kmeans(np.array(read_data(file_n)), k)