# import # ------------------------------------------------------------------------------------------ from .. import image import miam import copy import numpy as np import matplotlib.pyplot as plt # miam import import miam.image.Image as MIMG import miam.processing.ColorSpaceTransform as MCST import miam.histogram.Histogram as MHIST import miam.aesthetics.LightnessAesthetics as MLAC # ------------------------------------------------------------------------------------------ # MIAM project 2020 # ------------------------------------------------------------------------------------------ # author: remi.cozot@univ-littoral.fr # ------------------------------------------------------------------------------------------ class LightnessAesthetics(object): """description of class""" def __init__(self, centroids, **kwargs): self.lightnessClasses = centroids self.nbClass = len(self.lightnessClasses) self.nbBin = self.lightnessClasses[0].histValue.shape[0] def plot(self,ax): for j,aestheticsClass in enumerate(self.lightnessClasses): sum, sumB= 0.0,0.0 # compute mean for lightnessValue, binValue in enumerate(aestheticsClass.histValue): sumB = sumB + binValue sum= sum + binValue*aestheticsClass.edgeValue[lightnessValue+1] ax.plot(aestheticsClass.edgeValue[1:],aestheticsClass.histValue,miam.pltcolor[j]) ax.plot(sum/sumB,0,miam.pltcolor[j]+'o') def computeImageClass(self, image): # if required transform in Lab # note lightness class are in Lab image = MCST.ColorSpaceTransform().compute(image,dest='Lab') # compute lightness histogram hist = MHIST.Histogram.build(image,MIMG.channel.channel.L,nbBins=self.nbBin) # compute distance with classes distance = [] for i, aestheticsSignature in enumerate(self.lightnessClasses) : dist = MHIST.Histogram.computeDistance(aestheticsSignature,hist) distance.append(dist) return distance def projectImage(self,image,nbClass='all'): distance = self.computeImageClass(image) hLab = MHIST.Histogram.build(MCST.ColorSpaceTransform().compute(image,dest='Lab'),MIMG.channel.channel.L,nbBins=self.nbBin) res = copy.deepcopy(hLab) res.histValue = np.zeros(res.histValue.shape) if not nbClass: nbClass ="all" if isinstance(nbClass, str): if nbClass == "all": for i, aestheticsSignature in enumerate(self.lightnessClasses) : res = MHIST.Histogram.add(res, MHIST.Histogram.scale((1.0 - distance[i]),aestheticsSignature)) elif nbClass =="first": idxSort = np.argsort(np.asarray(distance)) res = MHIST.Histogram.scale((1.0 - distance[idxSort[0]]), self.lightnessClasses[idxSort[0]]) if isinstance(nbClass,range): idxSort = np.argsort(np.asarray(distance)) for i in nbClass: res = MHIST.Histogram.add(res,MHIST.Histogram.scale((1.0 - distance[idxSort[i]]), self.lightnessClasses[idxSort[i]])) return res.normalise(norm='dot') def readLightnessClasses(fileName, className = None): """ form np.load recover histogram of lightness classes""" if not className: className=['black','shadow','medium','highlight','white'] # from np.histogram to Histograms class centroids = np.load(fileName) nbClass, nbBin =centroids.shape edges = np.linspace(0,100,nbBin+1) # compute min to set name mean= [] for j,c in enumerate(centroids): sum, sumB= 0.0,0.0 # compute mean for i, binValue in enumerate(c): sumB = sumB + binValue sum= sum + binValue*edges[i+1] mean.append(sum/sumB) # sortIndex mean sortedIndex = np.argsort(mean) # build Histogram object lightnessClasses = [] for i, j in enumerate(sortedIndex): name = className[i] histValue = centroids[j] edgeValue = copy.deepcopy(edges) channel = MIMG.channel.channel.L colorSpace = MIMG.ColorSpace.ColorSpace.buildLab() log = False # build a histogram lightnessClasses.append(MHIST.Histogram(histValue, edgeValue, name,channel,logSpace = log)) return LightnessAesthetics(lightnessClasses)