TMO_Lightness.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. # import
  2. # ------------------------------------------------------------------------------------------
  3. from . import Processing, Ymap
  4. from . import ColorSpaceTransform
  5. from .. import image
  6. import colour, copy, skimage
  7. import numpy as np
  8. # ------------------------------------------------------------------------------------------
  9. # MIAM project 2020
  10. # ------------------------------------------------------------------------------------------
  11. # author: remi.cozot@univ-littoral.fr
  12. # ------------------------------------------------------------------------------------------
  13. class TMO_Lightness(Processing.Processing):
  14. """description of class"""
  15. def __init__(self):
  16. pass
  17. def compute(self, img, **kwargs):
  18. """
  19. Lightness tone mapping operator
  20. @params:
  21. img - Required : hdr image (miam.image.Image)
  22. kwargs - Optionnal : optionnal parameter (dict)
  23. 'removeZeros' : true|false (boolean)
  24. 'zerosPercentile' : pertencile of min/max values removed (float)
  25. """
  26. # take into account optionnal parameters given as dict
  27. removeZeros = False
  28. zerosPercentile = None
  29. if kwargs:
  30. if 'removeZeros' in kwargs:
  31. removeZeros = kwargs['removeZeros']
  32. if removeZeros:
  33. if 'zerosPercentile' in kwags:
  34. zerosPercentile = kwargs['zerosPercentile']
  35. else:
  36. print("WARNING[miam.processing.TMO_Lightness.compute(...): 'removeZeros'=True BUT no 'zerosPercentile' found! >> set to 0.0]")
  37. zerosPercentile = 0.0
  38. # result: first copy image
  39. res = copy.deepcopy(img)
  40. # can tone map HDR only
  41. if (img.type == image.imageType.imageType.HDR):
  42. # image preprocessing
  43. if removeZeros:
  44. if zerosPercentile==0:
  45. res = res.removeZeros()
  46. else:
  47. res = res.removeZeros().removeZeros(zerosPercentile)
  48. # Y cnannel
  49. Ychannel = ColorSpaceTransform.ColorSpaceTransform().compute(res,dest='XYZ').colorData[:,:,1]
  50. # min max
  51. minY,maxY = np.amin(Ychannel), np.amax(Ychannel)
  52. # use Log(Y) as L
  53. Lchannel = 100*(np.log10(Ychannel)-np.log10(minY))/(np.log10(maxY)-np.log10(minY))
  54. # go back to Y
  55. Lab = np.zeros(res.shape)
  56. Lab[:,:,0] = Lchannel
  57. sdrYchannel = colour.Lab_to_XYZ(Lab, illuminant=np.array([ 0.3127, 0.329 ]))[:,:,1]
  58. # remap Y
  59. res = res.process(Ymap.Ymap(),oldY=Ychannel,newY=sdrYchannel)
  60. # equalize
  61. #colorDataEQ = skimage.exposure.equalize_hist(res.colorData)
  62. # merge
  63. #alpha =0.50
  64. #res.colorData = alpha*res.colorData + (1-alpha)*colorDataEQ
  65. # encode
  66. imgRGBprime = colour.cctf_encoding(res.colorData,function='sRGB')
  67. # update attributes
  68. res.colorData = imgRGBprime
  69. res.type = image.imageType.imageType.SDR
  70. res.linear = False
  71. res.scalingFactor = 1.0
  72. res.colorSpace = colour.models.RGB_COLOURSPACES['sRGB'].copy()
  73. # reurn results
  74. return res.clip()