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 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")
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 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