Colours.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. import cv2
  2. import numpy
  3. import Tool
  4. class Colours(Tool.Tool):
  5. def on_init(self):
  6. self.id = "colours"
  7. self.name = "Colours"
  8. self.icon_path = "ui/PF2_Icons/Colours.png"
  9. self.properties = [
  10. Tool.Property("header", "Colours", "Header", None, has_toggle=False, has_button=False),
  11. Tool.Property("overall_saturation", "Saturation", "Slider", 0, max=50, min=-50),
  12. Tool.Property("hue", "Hue", "Slider", 0, max=50, min=-50),
  13. Tool.Property("kelvin", "Colour Temperature", "Slider", 6500, max=15000, min=1000),
  14. Tool.Property("header_ts", "Tonal Saturation", "Header", None, has_toggle=False, has_button=False),
  15. Tool.Property("highlight_saturation", "Highlight Saturation", "Slider", 0, max=50, min=-50),
  16. Tool.Property("midtone_saturation", "Midtone Saturation", "Slider", 0, max=50, min=-50),
  17. Tool.Property("shadow_saturation", "Shadow Saturation", "Slider", 0, max=50, min=-50),
  18. # Red
  19. Tool.Property("header_red", "Red", "Header", None, has_toggle=False, has_button=False),
  20. Tool.Property("red_overall_brightness", "Overall Brightness", "Slider", 0, max=50, min=-50),
  21. Tool.Property("red_highlight_brightness", "Highlight Brightness", "Slider", 0, max=50, min=-50),
  22. Tool.Property("red_midtone_brightness", "Midtone Brightness", "Slider", 0, max=50, min=-50),
  23. Tool.Property("red_shadow_brightness", "Shadow Brightness", "Slider", 0, max=50, min=-50),
  24. # Green
  25. Tool.Property("header_green", "Green", "Header", None, has_toggle=False, has_button=False),
  26. Tool.Property("green_overall_brightness", "Overall Brightness", "Slider", 0, max=50, min=-50),
  27. Tool.Property("green_highlight_brightness", "Highlight Brightness", "Slider", 0, max=50, min=-50),
  28. Tool.Property("green_midtone_brightness", "Midtone Brightness", "Slider", 0, max=50, min=-50),
  29. Tool.Property("green_shadow_brightness", "Shadow Brightness", "Slider", 0, max=50, min=-50),
  30. # Blue
  31. Tool.Property("header_blue", "Blue", "Header", None, has_toggle=False, has_button=False),
  32. Tool.Property("blue_overall_brightness", "Overall Brightness", "Slider", 0, max=50, min=-50),
  33. Tool.Property("blue_highlight_brightness", "Highlight Brightness", "Slider", 0, max=50, min=-50),
  34. Tool.Property("blue_midtone_brightness", "Midtone Brightness", "Slider", 0, max=50, min=-50),
  35. Tool.Property("blue_shadow_brightness", "Shadow Brightness", "Slider", 0, max=50, min=-50),
  36. # Bleed
  37. Tool.Property("header_bleed", "Tonal Bleed", "Header", None, has_toggle=False, has_button=False),
  38. Tool.Property("highlight_bleed", "Highlight Bleed", "Slider", 0.5, max=1, min=0.001),
  39. Tool.Property("midtone_bleed", "Midtone Bleed", "Slider", 0.5, max=1, min=0.001),
  40. Tool.Property("shadow_bleed", "Shadow Bleed", "Slider", 0.5, max=1, min=0.001),
  41. ]
  42. def on_update(self, image):
  43. if(not self.is_default()):
  44. im = image
  45. hue = self.props["hue"].get_value()
  46. saturation = self.props["overall_saturation"].get_value()
  47. ct = self.props["kelvin"].get_value()/100.0
  48. hs = self.props["highlight_saturation"].get_value()
  49. ms = self.props["midtone_saturation"].get_value()
  50. ss = self.props["shadow_saturation"].get_value()
  51. rob = self.props["red_overall_brightness"].get_value()
  52. rhb = self.props["red_highlight_brightness"].get_value()
  53. rmb = self.props["red_midtone_brightness"].get_value()
  54. rsb = self.props["red_shadow_brightness"].get_value()
  55. gob = self.props["green_overall_brightness"].get_value()
  56. ghb = self.props["green_highlight_brightness"].get_value()
  57. gmb = self.props["green_midtone_brightness"].get_value()
  58. gsb = self.props["green_shadow_brightness"].get_value()
  59. bob = self.props["blue_overall_brightness"].get_value()
  60. bhb = self.props["blue_highlight_brightness"].get_value()
  61. bmb = self.props["blue_midtone_brightness"].get_value()
  62. bsb = self.props["blue_shadow_brightness"].get_value()
  63. chbl = self.props["highlight_bleed"].get_value()
  64. cmbl = self.props["midtone_bleed"].get_value()
  65. csbl = self.props["shadow_bleed"].get_value()
  66. bpp = float(str(im.dtype).replace("uint", "").replace("float", ""))
  67. np = float(2 ** bpp - 1)
  68. out = im.astype(numpy.float32)
  69. isHr = self._is_highlight(out, (3.00 / chbl))
  70. isMr = self._is_midtone(out, (3.00 / cmbl))
  71. isSr = self._is_shadow(out, (3.00 / csbl))
  72. # Colour Temperature
  73. if(int(ct) != 65):
  74. r = 0
  75. if(ct <= 66):
  76. print(ct <= 66)
  77. r = 255
  78. else:
  79. r = ct - 60
  80. r = 329.698727446 * numpy.math.pow(r, -0.1332047592)
  81. if(r < 0):
  82. r = 0
  83. if(r > 255):
  84. r = 255
  85. g = 0
  86. if(ct <= 66):
  87. g = ct
  88. g = 99.4708025861 * numpy.math.log(g) - 161.1195681661
  89. if (g < 0):
  90. g = 0
  91. if (g > 255):
  92. g = 255
  93. else:
  94. g = ct - 60
  95. g = 288.1221695283 * numpy.math.pow(g, -0.0755148492)
  96. if (g < 0):
  97. g = 0
  98. if (g > 255):
  99. g = 255
  100. b = 0
  101. if(ct >= 66):
  102. b = 255
  103. elif(ct <= 19):
  104. b = 0
  105. else:
  106. b = ct - 10
  107. b = 138.5177312231 * numpy.math.log(b) - 305.0447927307
  108. if (b < 0):
  109. b = 0
  110. if (b > 255):
  111. b = 255
  112. r = (r/255.0)
  113. g = (g / 255.0)
  114. b = (b / 255.0)
  115. # Red
  116. out[0:, 0:, 2] = out[0:, 0:, 2] * r
  117. # Green
  118. out[0:, 0:, 1] = out[0:, 0:, 1] * g
  119. # Blue
  120. out[0:, 0:, 0] = out[0:, 0:, 0] * b
  121. #Converting to HSV
  122. out = cv2.cvtColor(out, cv2.COLOR_BGR2HSV)
  123. #Hue...
  124. if (hue != 0.0):
  125. out[0:, 0:, 0] = out[0:, 0:, 0] + (hue / 100.0) * 255
  126. #Saturation...
  127. if (saturation != 0.0):
  128. out[0:, 0:, 1] = out[0:, 0:, 1] + (saturation / 10000.0) * 255
  129. #Saturation Highlights...
  130. if (hs != 0.0):
  131. out[0:, 0:, 1] = (out[0:, 0:, 1] + ((hs * isHr[0:, 0:, 1]) / 10000.0) * 255)
  132. #Saturation Midtones...
  133. if (ms != 0.0):
  134. out[0:, 0:, 1] = (out[0:, 0:, 1] + ((ms * isMr[0:, 0:, 1]) / 10000.0) * 255)
  135. #Saturation Shadows...
  136. if (ss != 0.0):
  137. out[0:, 0:, 1] = (out[0:, 0:, 1] + ((ss * isSr[0:, 0:, 1]) / 10000.0) * 255)
  138. out[out < 0.0] = 0.0
  139. out[out > 4294967296.0] = 4294967296.0
  140. out = cv2.cvtColor(out, cv2.COLOR_HSV2BGR)
  141. #Red...
  142. if (rob != 0.0):
  143. out[0:, 0:, 2] = out[0:, 0:, 2] + (rob / 100.0) * np
  144. # Highlights
  145. if (rhb != 0.0):
  146. out[0:, 0:, 2] = (out[0:, 0:, 2] + ((rhb * isHr[0:, 0:, 1]) / 100.0) * np)
  147. # Midtones
  148. if (rmb != 0.0):
  149. out[0:, 0:, 2] = (out[0:, 0:, 2] + ((rmb * isMr[0:, 0:, 1]) / 100.0) * np)
  150. # Shadows
  151. if (rsb != 0.0):
  152. out[0:, 0:, 2] = (out[0:, 0:, 2] + ((rsb * isSr[0:, 0:, 1]) / 100.0) * np)
  153. #Green...
  154. if (gob != 0.0):
  155. out[0:, 0:, 1] = out[0:, 0:, 1] + (gob / 100.0) * np
  156. # Highlights
  157. if (ghb != 0.0):
  158. out[0:, 0:, 1] = (out[0:, 0:, 1] + ((ghb * isHr[0:, 0:, 1]) / 100.0) * np)
  159. # Midtones
  160. if (gmb != 0.0):
  161. out[0:, 0:, 1] = (out[0:, 0:, 1] + ((gmb * isMr[0:, 0:, 1]) / 100.0) * np)
  162. # Shadows
  163. if (gsb != 0.0):
  164. out[0:, 0:, 1] = (out[0:, 0:, 1] + ((gsb * isSr[0:, 0:, 1]) / 100.0) * np)
  165. #Blue...
  166. if (bob != 0.0):
  167. out[0:, 0:, 0] = out[0:, 0:, 0] + (bob / 100.0) * np
  168. # Highlights
  169. if (bhb != 0.0):
  170. out[0:, 0:, 0] = (out[0:, 0:, 0] + ((bhb * isHr[0:, 0:, 1]) / 100.0) * np)
  171. # Midtones
  172. if (bmb != 0.0):
  173. out[0:, 0:, 0] = (out[0:, 0:, 0] + ((bmb * isMr[0:, 0:, 1]) / 100.0) * np)
  174. # Shadows
  175. if (bsb != 0.0):
  176. out[0:, 0:, 0] = (out[0:, 0:, 0] + ((bsb * isSr[0:, 0:, 1]) / 100.0) * np)
  177. out[out < 0.0] = 0.0
  178. out[out > np] = np
  179. return out.astype(im.dtype)
  180. else:
  181. return image
  182. def _is_highlight(self, image, bleed_value = 6.0):
  183. bleed = float(image.max() / bleed_value)
  184. mif = image.max() / 3.0 * 2.0
  185. icopy = image.copy()
  186. icopy[icopy < mif - bleed] = 0.0
  187. icopy[(icopy < mif) * (icopy != 0.0)] = ((mif - (icopy[(icopy < mif) * (icopy != 0.0)])) / bleed) * -1 + 1
  188. icopy[icopy >= mif] = 1.0
  189. return icopy
  190. def _is_midtone(self, image, bleed_value = 6.0):
  191. bleed = float(image.max() / bleed_value)
  192. mif = image.max() / 3.0
  193. mir = image.max() / 3.0 * 2.0
  194. icopy = image.copy()
  195. icopy[icopy < mif - bleed] = 0.0
  196. icopy[icopy > mir + bleed] = 0.0
  197. icopy[(icopy < mif) * (icopy != 0.0)] = ((mif - (icopy[(icopy < mif) * (icopy != 0.0)])) / bleed) * -1 + 1
  198. icopy[(icopy > mir) * (icopy != 0.0)] = (((icopy[(icopy > mir) * (icopy != 0.0)]) - mir) / bleed) * -1 + 1
  199. icopy[(icopy >= mif) * (icopy <= mir)] = 1.0
  200. return icopy
  201. def _is_shadow(self, image, bleed_value=6.0):
  202. bleed = float(image.max() / bleed_value)
  203. mir = image.max() / 3.0
  204. icopy = image.copy()
  205. icopy[icopy <= mir] = 1.0
  206. icopy[icopy > mir + bleed] = 0.0
  207. icopy[icopy > mir] = (((icopy[(icopy > mir) * (icopy != 0.0)]) - mir) / bleed) * -1 + 1
  208. return icopy