123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- 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),
- Tool.Property("neighbour_bleed", "Neighbour Bleed", "Slider", 0.25, max=2.0, min=0.0),
- # 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()
- neighbour_bleed = self.props["neighbour_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))
- isHue = self._neighbour_bleed(isHue, neighbour_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
- def _neighbour_bleed(self, map, bleed):
- strength = bleed*30
- if (strength > 0):
- height, width = map.shape[:2]
- size = (height * width)
- mul = numpy.math.sqrt(size) / 1064.416 # numpy.math.sqrt(1132982.0)
- map = map*255
- blur_size = 2 * round((round(strength * mul) + 1) / 2) - 1
- im = cv2.blur(map, (int(blur_size), int(blur_size)))
- return im/255.0
- return map
|