LightnessAesthetics.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. # import
  2. # ------------------------------------------------------------------------------------------
  3. from .. import image
  4. import miam
  5. import copy
  6. import numpy as np
  7. import matplotlib.pyplot as plt
  8. # miam import
  9. import miam.image.Image as MIMG
  10. import miam.processing.ColorSpaceTransform as MCST
  11. import miam.histogram.Histogram as MHIST
  12. import miam.aesthetics.LightnessAesthetics as MLAC
  13. # ------------------------------------------------------------------------------------------
  14. # MIAM project 2020
  15. # ------------------------------------------------------------------------------------------
  16. # author: remi.cozot@univ-littoral.fr
  17. # ------------------------------------------------------------------------------------------
  18. class LightnessAesthetics(object):
  19. """description of class"""
  20. def __init__(self, centroids, **kwargs):
  21. self.lightnessClasses = centroids
  22. self.nbClass = len(self.lightnessClasses)
  23. self.nbBin = self.lightnessClasses[0].histValue.shape[0]
  24. def plot(self,ax):
  25. for j,aestheticsClass in enumerate(self.lightnessClasses):
  26. sum, sumB= 0.0,0.0
  27. # compute mean
  28. for lightnessValue, binValue in enumerate(aestheticsClass.histValue):
  29. sumB = sumB + binValue
  30. sum= sum + binValue*aestheticsClass.edgeValue[lightnessValue+1]
  31. ax.plot(aestheticsClass.edgeValue[1:],aestheticsClass.histValue,miam.pltcolor[j])
  32. ax.plot(sum/sumB,0,miam.pltcolor[j]+'o')
  33. def computeImageClass(self, image):
  34. # if required transform in Lab
  35. # note lightness class are in Lab
  36. image = MCST.ColorSpaceTransform().compute(image,dest='Lab')
  37. # compute lightness histogram
  38. hist = MHIST.Histogram.build(image,MIMG.channel.channel.L,nbBins=self.nbBin)
  39. # compute distance with classes
  40. distance = []
  41. for i, aestheticsSignature in enumerate(self.lightnessClasses) :
  42. dist = MHIST.Histogram.computeDistance(aestheticsSignature,hist)
  43. distance.append(dist)
  44. return distance
  45. def projectImage(self,image,nbClass='all'):
  46. distance = self.computeImageClass(image)
  47. hLab = MHIST.Histogram.build(MCST.ColorSpaceTransform().compute(image,dest='Lab'),MIMG.channel.channel.L,nbBins=self.nbBin)
  48. res = copy.deepcopy(hLab)
  49. res.histValue = np.zeros(res.histValue.shape)
  50. if not nbClass: nbClass ="all"
  51. if isinstance(nbClass, str):
  52. if nbClass == "all":
  53. for i, aestheticsSignature in enumerate(self.lightnessClasses) :
  54. res = MHIST.Histogram.add(res, MHIST.Histogram.scale((1.0 - distance[i]),aestheticsSignature))
  55. elif nbClass =="first":
  56. idxSort = np.argsort(np.asarray(distance))
  57. res = MHIST.Histogram.scale((1.0 - distance[idxSort[0]]), self.lightnessClasses[idxSort[0]])
  58. if isinstance(nbClass,range):
  59. idxSort = np.argsort(np.asarray(distance))
  60. for i in nbClass:
  61. res = MHIST.Histogram.add(res,MHIST.Histogram.scale((1.0 - distance[idxSort[i]]), self.lightnessClasses[idxSort[i]]))
  62. return res.normalise(norm='dot')
  63. def readLightnessClasses(fileName, className = None):
  64. """ form np.load recover histogram of lightness classes"""
  65. if not className: className=['black','shadow','medium','highlight','white']
  66. # from np.histogram to Histograms class
  67. centroids = np.load(fileName)
  68. nbClass, nbBin =centroids.shape
  69. edges = np.linspace(0,100,nbBin+1)
  70. # compute min to set name
  71. mean= []
  72. for j,c in enumerate(centroids):
  73. sum, sumB= 0.0,0.0
  74. # compute mean
  75. for i, binValue in enumerate(c):
  76. sumB = sumB + binValue
  77. sum= sum + binValue*edges[i+1]
  78. mean.append(sum/sumB)
  79. # sortIndex mean
  80. sortedIndex = np.argsort(mean)
  81. # build Histogram object
  82. lightnessClasses = []
  83. for i, j in enumerate(sortedIndex):
  84. name = className[i]
  85. histValue = centroids[j]
  86. edgeValue = copy.deepcopy(edges)
  87. channel = MIMG.channel.channel.L
  88. colorSpace = MIMG.ColorSpace.ColorSpace.buildLab()
  89. log = False
  90. # build a histogram
  91. lightnessClasses.append(MHIST.Histogram(histValue, edgeValue, name,channel,logSpace = log))
  92. return LightnessAesthetics(lightnessClasses)