# import # ------------------------------------------------------------------------------------------ import os import matplotlib.pyplot as plt import numpy as np import multiprocessing as mp import easygui import imageio # miam import import miam.image.Image as MIMG import miam.image.imageType as MTYPE import miam.image.channel as MCH import miam.processing.ColorSpaceTransform as MCST import miam.processing.TMO_Lightness as TMO_L import miam.processing.ContrastControl as PCC import miam.histogram.Histogram as MHIST import miam.aesthetics.LightnessAesthetics as MLAC import miam.aesthetics.Palette as MPAL import miam.imageDB.ImageDB import miam.imageDB.POGChecker import miam.imageDB.HwHDRBuilder import miam.html.generator import miam.utils import miam.pointcloud.PointCloud2D as MPC2D import miam.classification.kmeans import miam.math.Distance import miam.math.Normalize # ------------------------------------------------------------------------------------------ # MIAM project 2020 # ------------------------------------------------------------------------------------------ # author: remi.cozot@univ-littoral.fr # ------------------------------------------------------------------------------------------ # --------------------------------------------> Cluster # --------------------------------------------> Palette def clusterLightnessHist(): # ------------------------------------------------------------------------------------------ # # ------------------------------------------------------------------------------------------ # config: configfile jsonfile = "../DB/config_POG_DB.json" # histogram files # all lightness moments file allLightness_Moments = "../DB/POG_DB_L_Moments.npy" # all lightness histogram file allLightness_50bins = "../DB/POG_DB_L_Hists_50bins.npy" allLightness_100bins = "../DB/POG_DB_L_Hists_100bins.npy" # clusters centroids_L_Hists_50bins = "../DB/POG_DB_centroids_L_Hists_50bins.npy" assigments_L_Hists_50bins = "../DB/POG_DB_assigments_L_Hists_50bins.npy" assigmentsIdx_L_Hists_50bins = "../DB/POG_DB_assigmentsIdx_L_Hists_50bins.npy" distanceToCentroids = "../DB/POG_DB_dist_to_centroids_L_Hists_50bins.npy" # ------------------------------------------------------------------------------------------ # boolean to select what to do # ------------------------------------------------------------------------------------------ display_StdMean = True clusterHistograms = False computeDistToCentroids = False displayClusters = True distance1percent = False displayDistance = True displayBestPerClass = True # pog # ------------------------------------------------------------------------------------------ # loading POG pogDB = miam.imageDB.ImageDB.ImageDB(jsonConfigFile =jsonfile) pogDB.check(miam.imageDB.POGChecker.POGChecker(local=True)) print("MIAM[POG Cluster Lightness Histogram]") # POG: display Lightness Moments # ------------------------------------------------------------------------------------------ if display_StdMean: # load files allMoments = np.load(allLightness_Moments) # display plt.figure("Lightness: standard deviations/mean") plt.plot(allMoments[:,0],allMoments[:,1],'bo',markersize=2) pc = MPC2D.PointCloud2D(allMoments[:,0],allMoments[:,1]) xx, yy = MPC2D.PointCloud2D.toXYarray(pc.contour(0.05)) plt.plot(xx,yy,'r') plt.show(block=True) # POG: compute cluster Histograms # ------------------------------------------------------------------------------------------ if clusterHistograms: print("MIAM[",pogDB.name," clustering Lightness launch !]") allHists = np.load(allLightness_50bins) # k-means km = miam.classification.kmeans.kmeans(miam.math.Distance.Distance(miam.math.Distance.cosineDistance), miam.math.Normalize.Normalize(miam.math.Normalize.cosineNorm)) centroids,assigments,assigmentsIdx = km.kmeans(allHists, 5, 50, display = None) print("MIAM[",pogDB.name," clustering done !]") np.save(centroids_L_Hists_50bins,centroids) np.save(assigments_L_Hists_50bins,assigments) np.save(assigmentsIdx_L_Hists_50bins,assigmentsIdx) print("MIAM[",pogDB.name," clustering save saved !]") # POG: cluster analysis PART 1: distance to each centroids # ----------------------------------------------------------------------------------------- if computeDistToCentroids: # load files allHists = np.load(allLightness_50bins) # lightnesshsitograms allMoments = np.load(allLightness_Moments) # lightness moments mean, std, skewness centroids = np.load(centroids_L_Hists_50bins, allow_pickle = True) # centroids: 5 histograms assigments = np.load(assigments_L_Hists_50bins, allow_pickle = True) # assigments assigmentsIdx = np.load(assigmentsIdx_L_Hists_50bins, allow_pickle = True) # assigments index: for each histograms index of class print("MIAM[",pogDB.name," compute fo each distance to all centroid !]") # get data L_mean = allMoments[:,0] L_std = allMoments[:,1] # buid histogram objects hCentroids = [] for cent in centroids: c = MHIST.Histogram(cent,np.linspace(0,100,50+1),"hCentroid",MCH.channel.L) hCentroids.append(c) # distToCentroids distToCentroids = [] # distance to centroids for i, rawHist in enumerate(allHists): # get raw image histogram and build Histogram Object h = MHIST.Histogram(allHists[i],np.linspace(0,100,50+1),"h_"+str(i),MCH.channel.L) distToCent = [] for j,hc in enumerate(hCentroids): d = MHIST.Histogram.computeDistance(hc,h) distToCent.append(d) distToCentroids.append(distToCent) np.save(distanceToCentroids,distToCentroids) # POG: cluster analysis PART 2: aesthetics class # ----------------------------------------------------------------------------------------- if displayClusters: # load files allHists = np.load(allLightness_50bins) # lightnesshsitograms allMoments = np.load(allLightness_Moments) # lightness moments mean, std, skewness centroids = np.load(centroids_L_Hists_50bins, allow_pickle = True) # centroids: 5 histograms assigments = np.load(assigments_L_Hists_50bins, allow_pickle = True) # assigments assigmentsIdx = np.load(assigmentsIdx_L_Hists_50bins, allow_pickle = True) # assigments index: for each histograms index of class distToCentroids = np.load(distanceToCentroids, allow_pickle = True) # for each histograms/image distance to each cluster # get data L_mean = allMoments[:,0] L_std = allMoments[:,1] # -------------------------------------------- colors = ['b', 'g','r','c','m'] # plot number of assigments per cluster figNBA = plt.figure("number of assigments per cluster ['b', 'g','r','c','m']") nbAss = [] for i,p in enumerate(centroids): nbAss.append(len(assigmentsIdx[i])) plt.bar(colors,nbAss,color=colors) plt.show(block=False) # -------------------------------------------- # plot histograms numberOfCluster =5 fig, ax = plt.subplots(1,1) fig.suptitle("Centroids:"+str(numberOfCluster)+"/ Lightness Histograms ['b', 'g','r','c','m']") for i,c in enumerate(centroids): # create histograms object histoCentroids = MHIST.Histogram(c,np.linspace(0,100,50+1),"class("+str(i)+")",MCH.channel.L) # create image of palette histoCentroids.plot(ax,color=colors[i], title=True) #ax[1].plot(i*10,0,'o'+colors[i],markersize=10) #ax[1].axis("off") plt.show(block=False) # -------------------------------------------- plt.figure("Lightness: clusters") colors = ['b', 'g','r','c','m','y','k'] for i,assigmentId in enumerate(assigmentsIdx): print("assigmentId[",i,"].len:",len(assigmentId)) pc = MPC2D.PointCloud2D(L_mean[assigmentId],L_std[assigmentId]) # plot contour of clusters xx, yy = MPC2D.PointCloud2D.toXYarray(pc.contour(0.1)) plt.plot(xx,yy,colors[i%len(colors)]) plt.plot(L_mean[assigmentId],L_std[assigmentId],colors[i%len(colors)]+'o', markersize=1) plt.show(block=True) # ----------------------------------------------------------------------------------------- if distance1percent: # load files allHists = np.load(allLightness_50bins) # lightnesshsitograms allMoments = np.load(allLightness_Moments) # lightness moments mean, std, skewness centroids = np.load(centroids_L_Hists_50bins, allow_pickle = True) # centroids: 5 histograms assigments = np.load(assigments_L_Hists_50bins, allow_pickle = True) # assigments assigmentsIdx = np.load(assigmentsIdx_L_Hists_50bins, allow_pickle = True) # assigments index: for each histograms index of class distToCentroids = np.load(distanceToCentroids, allow_pickle = True) # for each histograms/image distance to each cluster # get data L_mean = allMoments[:,0] L_std = allMoments[:,1] colors = ['b', 'g','r','c','m','y','k'] plt.figure("Lightness: clusters 1%") for i, assigmentId in enumerate(assigmentsIdx): p25 = int(len(assigmentId) * 0.01) p100 = int(len(assigmentId) * 1.00) dd = distToCentroids[assigmentId,i] idxSorted = np.argsort(dd)#[::-1] i25 = idxSorted[0:p25] i100 = idxSorted[0:p100] ii25 = [assigmentId[k] for k in i25] ii100 = [assigmentId[k] for k in i100] pc25 = MPC2D.PointCloud2D(L_mean[ii25],L_std[ii25]) pc100 = MPC2D.PointCloud2D(L_mean[ii100],L_std[ii100]) xx25, yy25 = MPC2D.PointCloud2D.toXYarray(pc25.contour(0.1)) xx100, yy100 = MPC2D.PointCloud2D.toXYarray(pc100.contour(0.1)) plt.plot(xx25, yy25, colors[i%len(colors)]+"-.") plt.plot(xx100, yy100, colors[i%len(colors)]) plt.show(block=True) # ----------------------------------------------------------------------------------------- if displayDistance: print("MIAM[",pogDB.name," display distance !]") # load files allHists = np.load(allLightness_50bins) # lightnesshsitograms allMoments = np.load(allLightness_Moments) # lightness moments mean, std, skewness centroids = np.load(centroids_L_Hists_50bins, allow_pickle = True) # centroids: 5 histograms assigments = np.load(assigments_L_Hists_50bins, allow_pickle = True) # assigments assigmentsIdx = np.load(assigmentsIdx_L_Hists_50bins, allow_pickle = True) # assigments index: for each histograms index of class distToCentroids = np.load(distanceToCentroids, allow_pickle = True) # for each histograms/image distance to each cluster # get data fig, ax = plt.subplots(1,5) fig.suptitle('Distance to Histogram Class') colors = ['b', 'g','r','c','m','y','k'] # sort for i in range(5): idxSorted = np.argsort(distToCentroids[:,i])#[::-1] for j in range(5): ax[i].plot((distToCentroids[idxSorted[0:1000],j]),colors[j%len(colors)]+'o', markersize=1) plt.show(block=True) # ----------------------------------------------------------------------------------------- if displayBestPerClass: print("MIAM[display best image per class !]") # load files allHists = np.load(allLightness_50bins) # lightnesshsitograms allMoments = np.load(allLightness_Moments) # lightness moments mean, std, skewness centroids = np.load(centroids_L_Hists_50bins, allow_pickle = True) # centroids: 5 histograms assigments = np.load(assigments_L_Hists_50bins, allow_pickle = True) # assigments assigmentsIdx = np.load(assigmentsIdx_L_Hists_50bins, allow_pickle = True) # assigments index: for each histograms index of class distToCentroids = np.load(distanceToCentroids, allow_pickle = True) # for each histograms/image distance to each cluster # get data L_mean = allMoments[:,0] L_std = allMoments[:,1] colors = ['b', 'g','r','c','m','y','k'] # for each class for i in range(5): # histogram of class centroidHist = MHIST.Histogram(centroids[i,:],np.linspace(0,100,50+1),"",MCH.channel.L) # contour of class pc = MPC2D.PointCloud2D(L_mean[assigmentsIdx[i]],L_std[assigmentsIdx[i]]) xx, yy = MPC2D.PointCloud2D.toXYarray(pc.contour(0.1)) # sort image according to class distance idxSorted = np.argsort(distToCentroids[:,i]) # for ten best image of the current class for j in range(3): imagefilename = pogDB.db[idxSorted[j]] print("class(",i,"): best", j,">>",imagefilename) img = MIMG.Image.read(imagefilename) hist = MHIST.Histogram(allHists[idxSorted[j]],np.linspace(0,100,50+1),"",MCH.channel.L) # create figure fig, ax = plt.subplots(1,3) fig.suptitle("find 'best' image per class") centroidHist.plot(ax[0],colors[i%len(colors)]) hist.plot(ax[0],'k') ax[0].set_title('image (black) & centroid histogram') ax[1].plot(xx,yy,colors[i%len(colors)]) ax[1].plot(L_mean[idxSorted[j]],L_std[idxSorted[j]],'ko') ax[1].set_title('image lighness mean and constrast (black)/ contour of class') img.plot(ax[2]) ax[2].set_title('image') plt.show(block=True)