class XYZConversionTestCase(BaseColorConversionTest): def setUp(self): self.color = XYZColor(0.1, 0.2, 0.3) def test_conversion_to_xyy(self): xyy = convert_color(self.color, xyYColor) self.assertColorMatch(xyy, xyYColor(0.167, 0.333, 0.200)) def test_conversion_to_lab(self): lab = convert_color(self.color, LabColor) self.assertColorMatch(lab, LabColor(51.837, -57.486, -25.780)) def test_conversion_to_rgb(self): # Picked a set of XYZ coordinates that would return a good RGB value. self.color = XYZColor(0.300, 0.200, 0.300) rgb = convert_color(self.color, sRGBColor) self.assertColorMatch(rgb, sRGBColor(0.715, 0.349, 0.663)) def test_conversion_to_luv(self): luv = convert_color(self.color, LuvColor) self.assertColorMatch(luv, LuvColor(51.837, -73.561, -25.657)) def test_conversion_to_ipt(self): self.color.set_illuminant('D65') ipt = convert_color(self.color, IPTColor) self.assertColorMatch(ipt, IPTColor(0.5063, -0.3183, -0.1160)) def test_convert_to_self(self): same_color = convert_color(self.color, XYZColor) self.assertEqual(self.color, same_color)
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) elif isinstance(cobj, BT2020Color): if kwargs.get('is_12_bits_system'): a, b, c = 1.0993, 0.0181, 0.081697877417347 else: a, b, c = 1.099, 0.018, 0.08124794403514049 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
class chromaticAdaptationTestCase(unittest.TestCase): def setUp(self): self.color = XYZColor(0.5, 0.4, 0.1, illuminant='C') def test_adaptation_c_to_d65(self): self.color.apply_adaptation(target_illuminant='D65') self.assertAlmostEqual( self.color.xyz_x, 0.491, 3, "C to D65 adaptation failed: X coord") self.assertAlmostEqual( self.color.xyz_y, 0.400, 3, "C to D65 adaptation failed: Y coord") self.assertAlmostEqual( self.color.xyz_z, 0.093, 3, "C to D65 adaptation failed: Z coord") self.assertEqual( self.color.illuminant, 'd65', "C to D65 adaptation failed: Illuminant transfer")
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 """ from colormath.color_objects import XYZColor # Will contain linearized RGB channels (removed the gamma func). linear_channels = {} if cobj.rgb_type == "srgb": 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 = color_constants.RGB_SPECS[cobj.rgb_type]["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.rgb_type, convtype="rgb_to_xyz") if target_illuminant is None: target_illuminant = color_constants.RGB_SPECS[cobj.rgb_type]["native_illum"] # The illuminant of the original RGB object. This will always match # the RGB colorspace's native illuminant. illuminant = color_constants.RGB_SPECS[cobj.rgb_type]["native_illum"] 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 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 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 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 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 test_conversion_to_xyz(self): xyz = convert_color(self.color, XYZColor) self.assertColorMatch(xyz, XYZColor(0.001, 0.002, 0.003))
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_conversion_to_apple_rgb(self): self.color = XYZColor(0.0157, 0.0191, 0.0331) rgb = convert_color(self.color, AppleRGBColor) self.assertColorMatch(rgb, AppleRGBColor(0.0411, 0.1214, 0.1763))
def test_conversion_to_rgb(self): # Picked a set of XYZ coordinates that would return a good RGB value. self.color = XYZColor(0.300, 0.200, 0.300) rgb = convert_color(self.color, sRGBColor) self.assertColorMatch(rgb, sRGBColor(0.715, 0.349, 0.663))
def test_conversion_to_adobe_rgb(self): self.color = XYZColor(0.2553, 0.1125, 0.0011) rgb = convert_color(self.color, AdobeRGBColor) # This ends up getting clamped. self.assertColorMatch(rgb, AdobeRGBColor(0.6828, 0.0, 0.0))
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 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 = 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 setUp(self): self.color = XYZColor(0.1, 0.2, 0.3)
def XYZ_to(X,Y,Z,outc, which = None, si= None): "Converts an XYZ color to a target color space" if XYZColor: color = XYZColor(X, Y, Z) if outc == 'xyY': out = [X/(X+Y+Z),Y/(X+Y+Z),Y] elif 'RGB' in outc : if XYZColor and which not in [None, 'srgb-Nosi']: #THIS part gives fishy results since there is a whitepoint transformation # due to an assumed default illuminant (d65) no matter what color = XYZColor(X, Y, Z,) color.illuminant = si print "illuminant",color.illuminant print "color",color rgb = color.convert_to('rgb', target_rgb=which) out = [rgb.rgb_r/255., rgb.rgb_g/255., rgb.rgb_b/255.] else: #See http://en.wikipedia.org/wiki/SRGB M = np.matrix('3.2404542, -1.5371385, -0.4985314;\ -0.9692660, 1.8760108, 0.0415560;\ 0.0556434, -0.2040259, 1.0572252') # M = np.matrix('3.2406, -1.5372, -0.4986;\ # -0.9689, 1.8758, 0.0415;\ # 0.0557, -0.2040, 1.0570') XYZ = np.matrix('%f %f %f' % (X,Y,Z)) RGB = M * (XYZ.T) # print M # print RGB if RGB[0] > 0.0031308: if RGB[0] >= 1.0 : RGB[0] = 1.0 else: RGB[0] = (1.055 * math.pow(RGB[0], 1.0 / 2.4)) - 0.055 elif RGB[0] >= 0.0: RGB[0] = RGB[0] * 12.92 else: RGB[0] = 0.0 if RGB[1] > 0.0031308: if RGB[1] >= 1.0 : RGB[1] = 1.0 else: RGB[1] = (1.055 * math.pow(RGB[1], 1.0 / 2.4)) - 0.055 elif RGB[1] >= 0.0: RGB[1] = RGB[1] * 12.92 else: RGB[1] = 0.0 if RGB[2] > 0.0031308: if RGB[2] >= 1.0 : RGB[2] = 1.0 else: RGB[2] = (1.055 * math.pow(RGB[2], 1.0 / 2.4)) - 0.055 elif RGB[2] >= 0.0: RGB[2] = RGB[2] * 12.92 else: RGB[2] = 0.0 out = RGB elif outc == 'XYZ' : out = [X,Y,Z] else: out = NUL return out
def setUp(self): self.color = XYZColor(0.5, 0.4, 0.1, illuminant='C')
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
def test_conversion_to_xyz(self): xyz = convert_color(self.color, XYZColor) self.assertColorMatch(xyz, XYZColor(0.100, 0.200, 0.300))
# -*- 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_convert_to_XYZ(self): xyz = convert_color(self.color, XYZColor) self.assertColorMatch( xyz, XYZColor(0.4497, 0.2694, 0.0196, illuminant='d65', observer='2'))
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)