import cv2 import numpy import Tool class HueEqualiser(Tool.Tool): def on_init(self): self.id = "hueequaliser" self.name = "Hue Equaliser" self.icon_path = "ui/PF2_Icons/HueEqualiser.png" self.properties = [ Tool.Property("header", "Hue Equaliser", "Header", None, has_toggle=False, has_button=False), Tool.Property("bleed", "Hue Bleed", "Slider", 0.5, max=2.0, min=0.01), # Red Tool.Property("header_red", "Red", "Header", None, has_toggle=False, has_button=False), Tool.Property("red_value", "Value", "Slider", 0, max=50, min=-50), Tool.Property("red_saturation", "Saturation", "Slider", 0, max=50, min=-50), # Yellow Tool.Property("header_yellow", "Yellow", "Header", None, has_toggle=False, has_button=False), Tool.Property("yellow_value", "Value", "Slider", 0, max=50, min=-50), Tool.Property("yellow_saturation", "Saturation", "Slider", 0, max=50, min=-50), # Green Tool.Property("header_green", "Green", "Header", None, has_toggle=False, has_button=False), Tool.Property("green_value", "Value", "Slider", 0, max=50, min=-50), Tool.Property("green_saturation", "Saturation", "Slider", 0, max=50, min=-50), # Cyan Tool.Property("header_cyan", "Cyan", "Header", None, has_toggle=False, has_button=False), Tool.Property("cyan_value", "Value", "Slider", 0, max=50, min=-50), Tool.Property("cyan_saturation", "Saturation", "Slider", 0, max=50, min=-50), # Blue Tool.Property("header_blue", "Blue", "Header", None, has_toggle=False, has_button=False), Tool.Property("blue_value", "Value", "Slider", 0, max=50, min=-50), Tool.Property("blue_saturation", "Saturation", "Slider", 0, max=50, min=-50), # Violet Tool.Property("header_violet", "Violet", "Header", None, has_toggle=False, has_button=False), Tool.Property("violet_value", "Value", "Slider", 0, max=50, min=-50), Tool.Property("violet_saturation", "Saturation", "Slider", 0, max=50, min=-50), ] def on_update(self, image): hues = { "red": 0, "yellow": 60, "green": 120, "cyan": 180, "blue": 240, "violet": 300, "_red": 360, } out = image if(not self.is_default()): bleed = self.props["bleed"].get_value() out = out.astype(numpy.float32) # Convert to HSV colorspace out = cv2.cvtColor(out, cv2.COLOR_BGR2HSV) # Bits per pixel bpp = float(str(image.dtype).replace("uint", "").replace("float", "")) # Pixel value range np = float(2 ** bpp - 1) imhue = out[0:, 0:, 0] imsat = out[0:, 0:, 1] imval = out[0:, 0:, 2] for hue in hues: hsat = self.props["%s_saturation" % hue.replace('_', '')].get_value() hval = self.props["%s_value" % hue.replace('_', '')].get_value() isHue = self._is_hue(imhue, hues[hue], (3.5/bleed)) imsat = imsat + ((hsat / 10000) * 255) * isHue imval = imval + ((hval / 1000) * np) * isHue # Clip any values out of bounds imval[imval < 0.0] = 0.0 imval[imval > np] = np imsat[imsat < 0.0] = 0.0 imsat[imsat > 1.0] = 1.0 out[0:, 0:, 1] = imsat out[0:, 0:, 2] = imval # Convert back to BGR colorspace out = cv2.cvtColor(out, cv2.COLOR_HSV2BGR) out = out.astype(image.dtype) return out def _is_hue(self, image, hue_value, bleed_value = 3.5): mif = hue_value - 30 mir = hue_value + 30 if (mir > 360): mir = 360 if (mif < 0): mif = 0 bleed = float(360 / bleed_value) icopy = image.copy() print(bleed, mif, mir) if(mif != 0): icopy[icopy < mif - bleed] = 0.0 icopy[icopy > mir + bleed] = 0.0 icopy[(icopy < mif) * (icopy != 0.0)] = (((mif - (icopy[(icopy < mif) * (icopy != 0.0)]))/360.0) / (bleed/360.0)) * -1 + 1 icopy[(icopy > mir) * (icopy != 0.0)] = ((((icopy[(icopy > mir) * (icopy != 0.0)]) - mir)/360.0) / (bleed/360.0)) * -1 + 1 icopy[(icopy >= mif) * (icopy <= mir)] = 1.0 if(mif == 0): icopy[icopy > mir + bleed] = 0.0 icopy[(icopy > mir) * (icopy != 0.0)] = ((((icopy[(icopy > mir) * (icopy != 0.0)]) - mir) / 360.0) / (bleed/360.0)) * -1 + 1 return icopy