def Luv_to_XYZ(cobj, *args, **kwargs): """ Convert from Luv to XYZ. """ illum = cobj.get_illuminant_xyz() # Without Light, there is no color. Short-circuit this and avoid some # zero division errors in the var_a_frac calculation. if cobj.luv_l <= 0.0: xyz_x = 0.0 xyz_y = 0.0 xyz_z = 0.0 return XYZColor( xyz_x, xyz_y, xyz_z, observer=cobj.observer, illuminant=cobj.illuminant) # Various variables used throughout the conversion. cie_k_times_e = color_constants.CIE_K * color_constants.CIE_E u_sub_0 = (4.0 * illum["X"]) / (illum["X"] + 15.0 * illum["Y"] + 3.0 * illum["Z"]) v_sub_0 = (9.0 * illum["Y"]) / (illum["X"] + 15.0 * illum["Y"] + 3.0 * illum["Z"]) var_u = cobj.luv_u / (13.0 * cobj.luv_l) + u_sub_0 var_v = cobj.luv_v / (13.0 * cobj.luv_l) + v_sub_0 # Y-coordinate calculations. if cobj.luv_l > cie_k_times_e: xyz_y = math.pow((cobj.luv_l + 16.0) / 116.0, 3.0) else: xyz_y = cobj.luv_l / color_constants.CIE_K # X-coordinate calculation. xyz_x = xyz_y * 9.0 * var_u / (4.0 * var_v) # Z-coordinate calculation. xyz_z = xyz_y * (12.0 - 3.0 * var_u - 20.0 * var_v) / (4.0 * var_v) return XYZColor( xyz_x, xyz_y, xyz_z, illuminant=cobj.illuminant, observer=cobj.observer)
def test_srgb_conversion_to_xyz_d65(self): """ sRGB's native illuminant is D65. This is a straightforward conversion. """ xyz = convert_color(self.color, XYZColor) self.assertColorMatch(xyz, XYZColor(0.294, 0.457, 0.103))
def test_observer_guard(self): xyz = XYZColor(1, 1, 1, illuminant="d65", observer="10") def _ipt_conversion(): return convert_color(xyz, IPTColor) self.assertRaises(ValueError, _ipt_conversion)
def Lab_to_XYZ(cobj, *args, **kwargs): """ Convert from Lab to XYZ """ illum = cobj.get_illuminant_xyz() xyz_y = (cobj.lab_l + 16.0) / 116.0 xyz_x = cobj.lab_a / 500.0 + xyz_y xyz_z = xyz_y - cobj.lab_b / 200.0 if math.pow(xyz_y, 3) > color_constants.CIE_E: xyz_y = math.pow(xyz_y, 3) else: xyz_y = (xyz_y - 16.0 / 116.0) / 7.787 if math.pow(xyz_x, 3) > color_constants.CIE_E: xyz_x = math.pow(xyz_x, 3) else: xyz_x = (xyz_x - 16.0 / 116.0) / 7.787 if math.pow(xyz_z, 3) > color_constants.CIE_E: xyz_z = math.pow(xyz_z, 3) else: xyz_z = (xyz_z - 16.0 / 116.0) / 7.787 xyz_x = (illum["X"] * xyz_x) xyz_y = (illum["Y"] * xyz_y) xyz_z = (illum["Z"] * xyz_z) return XYZColor( xyz_x, xyz_y, xyz_z, observer=cobj.observer, illuminant=cobj.illuminant)
def RGB_SS(): X = np.sum(SunShine * CIEx) Y = np.sum(SunShine * CIEy) Z = np.sum(SunShine * CIEz) tmp=XYZColor(X*100/Y,Y*100/Y,Z*100/Y) rgb=convert_color(tmp,sRGBColor) return rgb
def test_srgb_conversion_to_xyz_d50(self): """ sRGB's native illuminant is D65. Test the XYZ adaptations by setting a target illuminant to something other than D65. """ xyz = convert_color(self.color, XYZColor, target_illuminant='D50') self.assertColorMatch(xyz, XYZColor(0.313, 0.460, 0.082))
def convert_xyz_to_rgb( xyz_pixel: ndarray) \ -> ndarray: """ Convert color in numpy.ndarray from XYZ to RGB color space. """ # ----------------------------------------------------------------------- # return array( convert_color(XYZColor(*xyz_pixel, illuminant='d65', observer='2'), sRGBColor).get_value_tuple())
def RGB_to_XYZ(cobj, target_illuminant=None, *args, **kwargs): """ RGB to XYZ conversion. Expects RGB values between 0 and 255. Based off of: http://www.brucelindbloom.com/index.html?Eqn_RGB_to_XYZ.html """ # Will contain linearized RGB channels (removed the gamma func). linear_channels = {} if isinstance(cobj, sRGBColor): for channel in ["r", "g", "b"]: V = getattr(cobj, "rgb_" + channel) if V <= 0.04045: linear_channels[channel] = V / 12.92 else: linear_channels[channel] = math.pow((V + 0.055) / 1.055, 2.4) elif isinstance(cobj, BT2020Color): if kwargs.get("is_12_bits_system"): a, b, c = 1.0993, 0.0181, 0.081697877417347 # noqa else: a, b, c = 1.099, 0.018, 0.08124794403514049 # noqa for channel in ["r", "g", "b"]: V = getattr(cobj, "rgb_" + channel) if V <= c: linear_channels[channel] = V / 4.5 else: linear_channels[channel] = math.pow((V + (a - 1)) / a, 1 / 0.45) else: # If it's not sRGB... gamma = cobj.rgb_gamma for channel in ["r", "g", "b"]: V = getattr(cobj, "rgb_" + channel) linear_channels[channel] = math.pow(V, gamma) # Apply an RGB working space matrix to the XYZ values (matrix mul). xyz_x, xyz_y, xyz_z = apply_RGB_matrix( linear_channels["r"], linear_channels["g"], linear_channels["b"], rgb_type=cobj, convtype="rgb_to_xyz", ) if target_illuminant is None: target_illuminant = cobj.native_illuminant # The illuminant of the original RGB object. This will always match # the RGB colorspace's native illuminant. illuminant = cobj.native_illuminant xyzcolor = XYZColor(xyz_x, xyz_y, xyz_z, illuminant=illuminant) # This will take care of any illuminant changes for us (if source # illuminant != target illuminant). xyzcolor.apply_adaptation(target_illuminant) return xyzcolor
def run(): # Assign configuration variables. # The configuration check takes care they are present. conf = load_json(CONFIG_FILE) try: identity = conf[args.host].get('identity') psk = conf[args.host].get('key') api_factory = APIFactory(host=args.host, psk_id=identity, psk=psk) except KeyError: identity = uuid.uuid4().hex api_factory = APIFactory(host=args.host, psk_id=identity) try: psk = yield from api_factory.generate_psk(args.key) print('Generated PSK: ', psk) conf[args.host] = {'identity': identity, 'key': psk} save_json(CONFIG_FILE, conf) except AttributeError: raise PytradfriError("Please provide your Key") api = api_factory.request gateway = Gateway() devices_command = gateway.get_devices() devices_commands = yield from api(devices_command) devices = yield from api(devices_commands) lights = [dev for dev in devices if dev.has_light_control] rgb = (0, 0, 102) # Convert RGB to XYZ using a D50 illuminant. xyz = convert_color(sRGBColor(rgb[0], rgb[1], rgb[2]), XYZColor, observer='2', target_illuminant='d65') xy = int(xyz.xyz_x), int(xyz.xyz_y) # Assuming lights[3] is a RGB bulb xy_command = lights[3].light_control.set_xy_color(xy[0], xy[1]) yield from api(xy_command) # Assuming lights[3] is a RGB bulb xy = lights[3].light_control.lights[0].xy_color # Normalize Z Z = int(lights[3].light_control.lights[0].dimmer/254*65535) xyZ = xy+(Z,) rgb = convert_color(XYZColor(xyZ[0], xyZ[1], xyZ[2]), sRGBColor, observer='2', target_illuminant='d65') rgb = (int(rgb.rgb_r), int(rgb.rgb_g), int(rgb.rgb_b)) print(rgb) yield from asyncio.sleep(120)
def test_adobe_conversion_to_xyz_d65(self): """ Adobe RGB's native illuminant is D65, like sRGB's. However, sRGB uses different conversion math that uses gamma, so test the alternate logic route for non-sRGB RGB colors. """ adobe = AdobeRGBColor(0.482, 0.784, 0.196) xyz = convert_color(adobe, XYZColor) self.assertColorMatch(xyz, XYZColor(0.230, 0.429, 0.074))
def jch(start, amount, saturation, luminosity): k = 360/amount ans = ((luminosity, saturation, start + i*k) for i in range(amount)) ans = (cspace_convert(color, "JCh", "XYZ1") for color in ans) ans = (XYZColor(*color.tolist()) for color in ans) ans = (convert_color(color, AdobeRGBColor, target_illuminant="d65") for color in ans) ans = ((color.clamped_rgb_r, color.clamped_rgb_g, color.clamped_rgb_b) for color in ans) ans = ((round(r*255), round(g*255), round(b*255)) for r, g, b in ans) ans = (("#%02x%02x%02x" % (r, g, b), r, g, b) for r, g, b in ans) return ans
def RGB(Spec,griglia,depth): S_col=ipl.interp1d(griglia,Spec,kind='linear')(lambdas_col) zxy=XYZ(S_col, depth) rgb=np.empty(zxy.shape) rgb_ss=RGB_SS() for ii, xyz in enumerate(zxy): tmp=XYZColor(xyz[0],xyz[1],xyz[2]) tmp2=convert_color(tmp,sRGBColor) rgb[ii,:]=np.array([tmp2.rgb_r/rgb_ss.rgb_r,tmp2.rgb_g/rgb_ss.rgb_g,tmp2.rgb_b/rgb_ss.rgb_b]) return rgb
def test_adobe_conversion_to_xyz_d50(self): """ Adobe RGB's native illuminant is D65, so an adaptation matrix is involved here. However, the math for sRGB and all other RGB types is different, so test all of the other types with an adaptation matrix here. """ adobe = AdobeRGBColor(0.482, 0.784, 0.196) xyz = convert_color(adobe, XYZColor, target_illuminant='D50') self.assertColorMatch(xyz, XYZColor(0.247, 0.431, 0.060))
def Spectral_to_XYZ(cobj, illuminant_override=None, *args, **kwargs): """ Converts spectral readings to XYZ. """ # If the user provides an illuminant_override numpy array, use it. if illuminant_override: reference_illum = illuminant_override else: # Otherwise, look up the illuminant from known standards based # on the value of 'illuminant' pulled from the SpectralColor object. try: reference_illum = spectral_constants.REF_ILLUM_TABLE[ cobj.illuminant] except KeyError: raise InvalidIlluminantError(cobj.illuminant) # Get the spectral distribution of the selected standard observer. if cobj.observer == '10': std_obs_x = spectral_constants.STDOBSERV_X10 std_obs_y = spectral_constants.STDOBSERV_Y10 std_obs_z = spectral_constants.STDOBSERV_Z10 else: # Assume 2 degree, since it is theoretically the only other possibility. std_obs_x = spectral_constants.STDOBSERV_X2 std_obs_y = spectral_constants.STDOBSERV_Y2 std_obs_z = spectral_constants.STDOBSERV_Z2 # This is a NumPy array containing the spectral distribution of the color. sample = cobj.get_numpy_array() # The denominator is constant throughout the entire calculation for X, # Y, and Z coordinates. Calculate it once and re-use. denom = std_obs_y * reference_illum # This is also a common element in the calculation whereby the sample # NumPy array is multiplied by the reference illuminant's power distribution # (which is also a NumPy array). sample_by_ref_illum = sample * reference_illum # Calculate the numerator of the equation to find X. x_numerator = sample_by_ref_illum * std_obs_x y_numerator = sample_by_ref_illum * std_obs_y z_numerator = sample_by_ref_illum * std_obs_z xyz_x = x_numerator.sum() / denom.sum() xyz_y = y_numerator.sum() / denom.sum() xyz_z = z_numerator.sum() / denom.sum() return XYZColor(xyz_x, xyz_y, xyz_z, observer=cobj.observer, illuminant=cobj.illuminant)
def xyY_to_XYZ(cobj, *args, **kwargs): """ Convert from xyY to XYZ. """ xyz_x = (cobj.xyy_x * cobj.xyy_Y) / cobj.xyy_y xyz_y = cobj.xyy_Y xyz_z = ((1.0 - cobj.xyy_x - cobj.xyy_y) * xyz_y) / cobj.xyy_y return XYZColor( xyz_x, xyz_y, xyz_z, illuminant=cobj.illuminant, observer=cobj.observer)
def IPT_to_XYZ(cobj, *args, **kwargs): """ Converts XYZ to IPT. """ ipt_values = numpy.array(cobj.get_value_tuple()) lms_values = numpy.dot(numpy.linalg.inv(IPTColor.conversion_matrices['lms_to_ipt']), ipt_values) lms_prime = numpy.sign(lms_values) * numpy.abs(lms_values) ** (1 / 0.43) xyz_values = numpy.dot(numpy.linalg.inv(IPTColor.conversion_matrices['xyz_to_lms']), lms_prime) return XYZColor(*xyz_values, observer='2', illuminant='d65')
def example_lab_to_ipt(): """ This function shows a simple conversion of an XYZ color to an IPT color. """ print("=== Simple Example: XYZ->IPT ===") # Instantiate an XYZ color object with the given values. xyz = XYZColor(0.5, 0.5, 0.5, illuminant="d65") # Show a string representation. print(xyz) # Convert to IPT. ipt = convert_color(xyz, IPTColor) print(ipt) print("=== End Example ===\n")
def IPT_to_XYZ(cobj, *args, **kwargs): """ Converts IPT to XYZ. """ ipt_values = numpy.array(cobj.get_value_tuple()) lms_values = numpy.dot( numpy.linalg.inv(IPTColor.conversion_matrices["lms_to_ipt"]), ipt_values ) lms_prime = numpy.sign(lms_values) * numpy.abs(lms_values) ** (1 / 0.43) xyz_values = numpy.dot( numpy.linalg.inv(IPTColor.conversion_matrices["xyz_to_lms"]), lms_prime ) return XYZColor(*xyz_values, observer="2", illuminant="d65")
def xyY_to_XYZ(cobj, *args, **kwargs): """ Convert from xyY to XYZ. """ # avoid division by zero if cobj.xyy_y == 0.0: xyz_x = 0.0 xyz_y = 0.0 xyz_z = 0.0 else: xyz_x = (cobj.xyy_x * cobj.xyy_Y) / cobj.xyy_y xyz_y = cobj.xyy_Y xyz_z = ((1.0 - cobj.xyy_x - cobj.xyy_y) * xyz_y) / cobj.xyy_y return XYZColor( xyz_x, xyz_y, xyz_z, illuminant=cobj.illuminant, observer=cobj.observer)
def xyb_to_rgba(self, x, y, dimmer): _x = x / 65535 _y = y / 65535 _z = (1.0 - _x - _y) # _z = (dimmer / 254 * 65535) rgb = convert_color(XYZColor(_x, _y, _z), sRGBColor, observer='2', target_illuminant='d65') r, g, b = (rgb.rgb_r, rgb.rgb_g, rgb.rgb_b) a = dimmer / 254 # rospy.loginfo('r: {}, g: {}, b: {}, a: {}'.format(r, g, b, a)) return (r, g, b, a)
def run(): # Assign configuration variables. # The configuration check takes care they are present. api_factory = APIFactory(sys.argv[1]) with open('gateway_psk.txt', 'a+') as file: file.seek(0) psk = file.read() if psk: api_factory.psk = psk.strip() else: psk = api_factory.generate_psk(sys.argv[2]) print('Generated PSK: ', psk) file.write(psk) api = api_factory.request gateway = Gateway() devices_command = gateway.get_devices() devices_commands = api(devices_command) devices = api(devices_commands) lights = [dev for dev in devices if dev.has_light_control] rgb = (0, 0, 102) # Convert RGB to XYZ using a D50 illuminant. xyz = convert_color(sRGBColor(rgb[0], rgb[1], rgb[2]), XYZColor, observer='2', target_illuminant='d65') xy = int(xyz.xyz_x), int(xyz.xyz_y) # Assuming lights[3] is a RGB bulb api(lights[3].light_control.set_xy_color(xy[0], xy[1])) # Assuming lights[3] is a RGB bulb xy = lights[3].light_control.lights[0].xy_color # Normalize Z Z = int(lights[3].light_control.lights[0].dimmer / 254 * 65535) xyZ = xy + (Z, ) rgb = convert_color(XYZColor(xyZ[0], xyZ[1], xyZ[2]), sRGBColor, observer='2', target_illuminant='d65') rgb = (int(rgb.rgb_r), int(rgb.rgb_g), int(rgb.rgb_b)) print(rgb)
def color_from_position(self, position): """Returns a unique RGB color for each position on the map. :position: TODO :returns: TODO """ # normalize the position on the map to a position in the colorspace x = position[0] / self.size[0] # / 2 y = position[1] / self.size[1] # /2 z = 1 - x - y xyz = XYZColor(x, y, z) rgb = convert_color(xyz, sRGBColor) rgb_tuple = (rgb.clamped_rgb_r, rgb.clamped_rgb_g, rgb.clamped_rgb_b) return rgb_tuple
def RGB_to_XYZ(cobj, target_illuminant=None, *args, **kwargs): """ RGB to XYZ conversion. Expects 0-255 RGB values. Based off of: http://www.brucelindbloom.com/index.html?Eqn_RGB_to_XYZ.html """ # Will contain linearized RGB channels (removed the gamma func). linear_channels = {} if isinstance(cobj, sRGBColor): for channel in ['r', 'g', 'b']: V = getattr(cobj, 'rgb_' + channel) if V <= 0.04045: linear_channels[channel] = V / 12.92 else: linear_channels[channel] = math.pow((V + 0.055) / 1.055, 2.4) else: # If it's not sRGB... gamma = cobj.rgb_gamma for channel in ['r', 'g', 'b']: V = getattr(cobj, 'rgb_' + channel) linear_channels[channel] = math.pow(V, gamma) # Apply an RGB working space matrix to the XYZ values (matrix mul). xyz_x, xyz_y, xyz_z = apply_RGB_matrix(linear_channels['r'], linear_channels['g'], linear_channels['b'], rgb_type=cobj, convtype="rgb_to_xyz") if target_illuminant is None: target_illuminant = cobj.native_illuminant # The illuminant of the original RGB object. This will always match # the RGB colorspace's native illuminant. illuminant = cobj.native_illuminant xyzcolor = XYZColor(xyz_x, xyz_y, xyz_z, illuminant=illuminant) # This will take care of any illuminant changes for us (if source # illuminant != target illuminant). xyzcolor.apply_adaptation(target_illuminant) return xyzcolor
def test_conversion_to_xyz(self): xyz = convert_color(self.color, XYZColor) self.assertColorMatch(xyz, XYZColor(0.115, 0.099, 0.047))
def XYZ2Lab(xyz): obj = XYZColor(*(xyz)) lab = convert_color(XYZColor(*(xyz)), LabColor, target_illuminant='d65') return lab
# -*- coding: utf-8 -*- from colormath.color_appearance_models import CIECAM02 from colormath.color_objects import XYZColor # Color stimulus color = XYZColor(19.01, 20, 21.78) # Illuminant illuminant_d65 = XYZColor(95.05, 100, 108.88) # Background relative luminance y_b_dark = 10 y_b_light = 100 # Adapting luminance l_a = 328.31 # Surround condition assumed to be average (see CIECAM02 documentation for values) c = 0.69 n_c = 1 f = 1 model_a = CIECAM02( color.xyz_x, color.xyz_y, color.xyz_z, illuminant_d65.xyz_x, illuminant_d65.xyz_y, illuminant_d65.xyz_z, y_b_dark, l_a,
def test_observer_guard(self): xyz = XYZColor(1, 1, 1, illuminant='d65', observer='10') ipt_conversion = lambda: convert_color(xyz, IPTColor) self.assertRaises(ValueError, ipt_conversion)
def setUp(self): self.color = XYZColor(0.5, 0.4, 0.1, illuminant='C')
async def run(): # Assign configuration variables. # The configuration check takes care they are present. conf = load_json(CONFIG_FILE) try: identity = conf[args.host].get("identity") psk = conf[args.host].get("key") api_factory = await APIFactory.init(host=args.host, psk_id=identity, psk=psk) except KeyError: identity = uuid.uuid4().hex api_factory = await APIFactory.init(host=args.host, psk_id=identity) try: psk = await api_factory.generate_psk(args.key) print("Generated PSK: ", psk) conf[args.host] = {"identity": identity, "key": psk} save_json(CONFIG_FILE, conf) except AttributeError: raise PytradfriError("Please provide the 'Security Code' on the " "back of your Tradfri gateway using the " "-K flag.") api = api_factory.request gateway = Gateway() devices_command = gateway.get_devices() devices_commands = await api(devices_command) devices = await api(devices_commands) lights = [dev for dev in devices if dev.has_light_control] rgb = (0, 0, 102) # Convert RGB to XYZ using a D50 illuminant. xyz = convert_color( sRGBColor(rgb[0], rgb[1], rgb[2]), XYZColor, observer="2", target_illuminant="d65", ) xy = int(xyz.xyz_x), int(xyz.xyz_y) light = None # Find a bulb that can set color for dev in lights: if dev.light_control.can_set_color: light = dev break if not light: print("No color bulbs found") return xy_command = light.light_control.set_xy_color(xy[0], xy[1]) await api(xy_command) xy = light.light_control.lights[0].xy_color # Normalize Z Z = int(light.light_control.lights[0].dimmer / 254 * 65535) xyZ = xy + (Z, ) rgb = convert_color( XYZColor(xyZ[0], xyZ[1], xyZ[2]), sRGBColor, observer="2", target_illuminant="d65", ) rgb = (int(rgb.rgb_r), int(rgb.rgb_g), int(rgb.rgb_b)) print(rgb) await asyncio.sleep(120) await api_factory.shutdown()
def test_convert_to_XYZ(self): xyz = convert_color(self.color, XYZColor) self.assertColorMatch( xyz, XYZColor(0.4497, 0.2694, 0.0196, illuminant='d65', observer='2'))