def color_correct(image, ref_color_checker, plot=False, method='Cheung 2004', **kwargs): assert method in {'Finlayson 2015', 'Cheung 2004', 'Vandermonde'} # Find the color checker swatches swatches = detect_colour_checkers_segmentation(image)[0][::-1] # define D65 as the standard illuminant we will use D65 = colour.ILLUMINANTS['CIE 1931 2 Degree Standard Observer']['D65'] # convert the reference color checker to RGB, by going through XYZ and using the D65 illuminant ref_color_checker_RGB = colour.XYZ_to_RGB( colour.xyY_to_XYZ(list(ref_color_checker.data.values())), ref_color_checker.illuminant, D65, colour.RGB_COLOURSPACES['sRGB'].XYZ_to_RGB_matrix) # plot the color checkers overlapped with the colors extracted from the image if plot: # convert the uncorrected swatches extracted from the image from RGB to xyY by going through XYZ swatches_xyY = colour.XYZ_to_xyY( colour.RGB_to_XYZ( swatches, D65, D65, colour.RGB_COLOURSPACES['sRGB'].RGB_to_XYZ_matrix)) # use the RGB reference color checker to correct just the color checker swatches from the image swatches_corrected = colour.colour_correction(swatches, swatches, ref_color_checker_RGB, method=method, **kwargs) # convert these color corrected swatches from RGB to xyY by going through XYZ swatches_corrected_xyY = colour.XYZ_to_xyY( colour.RGB_to_XYZ( swatches_corrected, D65, D65, colour.RGB_COLOURSPACES['sRGB'].RGB_to_XYZ_matrix)) image_colour_checker = colour.characterisation.ColourChecker( 'Uncorrected Image', OrderedDict(zip(ref_color_checker.data.keys(), swatches_xyY)), D65) image_colour_checker_corrected = colour.characterisation.ColourChecker( 'Corrected Image with {:}'.format(method), OrderedDict( zip(ref_color_checker.data.keys(), swatches_corrected_xyY)), D65) plot_multi_colour_checkers([ref_color_checker, image_colour_checker]) plot_multi_colour_checkers( [ref_color_checker, image_colour_checker_corrected]) return colour.colour_correction(image, swatches, ref_color_checker_RGB, method=method, **kwargs)
def sRgbToHdr(source: tuple[int, int, int]) -> tuple[int, int, int]: """ 大致思路:先做gamma correction,然后转入XYZ。 在xyY内将Y的极值由sRGB亮度调为输出 亮度,然后转回输出色域的RGB。 args: colour -- (0-255, 0-255, 0-255) """ if source == (0, 0, 0): return (0, 0, 0) args = parse_args() srgb_brightness = args.sub_brightness screen_brightness = args.output_brightness target_colourspace = RGB_COLOURSPACE_BT2020 if args.colourspace == 'dcip3': target_colourspace = RGB_COLOURSPACE_DCI_P3 normalized_source = np.array(source) / 255 linear_source = colour.oetf_inverse(normalized_source, 'ITU-R BT.709') xyz = colour.RGB_to_XYZ(linear_source, RGB_COLOURSPACE_sRGB.whitepoint, D65_ILLUMINANT, RGB_COLOURSPACE_sRGB.matrix_RGB_to_XYZ) xyy = colour.XYZ_to_xyY(xyz) srgb_luma = xyy[2] xyy[2] = xyy[2] * srgb_brightness / screen_brightness xyz = colour.xyY_to_XYZ(xyy) output = colour.XYZ_to_RGB(xyz, D65_ILLUMINANT, target_colourspace.whitepoint, target_colourspace.matrix_XYZ_to_RGB) output = apply_oetf(output, srgb_luma) output = np.trunc(output * 255) return (int(output[0]), int(output[1]), int(output[2]))
def fXYZtoxyY(XYZimage): # Converts image from XYZ to xyY # Note that the function colour.XYZ_to_xyY(imgXYZ) is wrong: it converts [000] to white xyYimage = colour.XYZ_to_xyY(XYZimage) # correct for 000 to get 000 not white dim = XYZimage.shape for i in range(dim[0]): for j in range(dim[1]): if XYZimage[i, j, 1] == 0: # If intensity=0 set to black xyYimage[i, j, :] = 0 return xyYimage
def _rgb_to_ciexyy(img: np.ndarray, backend: Optional[str] = None, **kwargs: Any) -> np.ndarray: """ not finished, finished part checked, convert `img` from the color space of RGB to the color space of CIExyY Parameters ---------- img: ndarray, the image, in the format (color space) RGB8, be converted to CIExyY backend: str, default `_CVT_COLOR_BACKEND`, currently can be one in `_AVAILABLE_CVT_COLOR_BACKENDS`, the backend to perform the color space conversion kwargs: dict, not used, only to be compatible with other color space conversion functions Returns ------- cie_xyy: ndarray, `img` in the format (color space) of CIExyY """ if backend is None: # backend = _CVT_COLOR_BACKEND # no such method in cv2 backend = "colour-science" if backend.lower() == "cv2": pass elif backend.lower() == "colour-science": cie_xyy = colour.XYZ_to_xyY( _rgb_to_ciexyz(img, backend="colour-science", **kwargs)) elif backend.lower() == "pil": pass elif backend.lower() == "naive": # default_white_point = np.array([0.3127, 0.3290, 0.0]) # img_xyz = _rgb_to_ciexyz(img=img, backend=backend, **kwargs) pass return cie_xyy
#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Showcases colour models computations. """ import colour from colour.utilities.verbose import message_box message_box('Colour Models Computations') XYZ = (1.14176346, 1.00000000, 0.49815206) message_box(('Converting to "CIE xyY" colourspace from given "CIE XYZ" ' 'tristimulus values:\n' '\n\t{0}'.format(XYZ))) print(colour.XYZ_to_xyY(XYZ)) print('\n') message_box(('The default illuminant if X == Y == Z == 0 is ' '"CIE Standard Illuminant D Series D50".')) print(colour.XYZ_to_xyY((0.00000000, 0.00000000, 0.00000000))) print('\n') message_box('Using an alternative illuminant.') print( colour.XYZ_to_xyY( (0.00000000, 0.00000000, 0.00000000), colour.ILLUMINANTS['CIE 1931 2 Degree Standard Observer']['D60']))
# -*- coding: utf-8 -*- """ Showcases colour models computations. """ import colour from colour.utilities.verbose import message_box message_box('Colour Models Computations') XYZ = [1.14176346, 1., 0.49815206] message_box(('Converting to "CIE xyY" colourspace from given "CIE XYZ" ' 'colourspace values:\n' '\n\t{0}'.format(XYZ))) print(colour.XYZ_to_xyY(XYZ)) print('\n') message_box(('The default illuminant if X == Y == Z == 0 is ' 'CIE Standard Illuminant D Series D50".')) print(colour.XYZ_to_xyY([0, 0, 0])) print('\n') message_box('Using an alternative illuminant.') print(colour.XYZ_to_xyY( [0, 0, 0], colour.ILLUMINANTS['CIE 1931 2 Degree Standard Observer']['D60'])) print('\n')
import numpy as np import colour RGB_r = np.array([1, 0, 0]) RGB_g = np.array([0, 1, 0]) RGB_b = np.array([0, 0, 1]) XYZ_r = colour.sRGB_to_XYZ(RGB_r, apply_EOCF=False) XYZ_g = colour.sRGB_to_XYZ(RGB_g, apply_EOCF=False) XYZ_b = colour.sRGB_to_XYZ(RGB_b, apply_EOCF=False) xyY_r = colour.XYZ_to_xyY(XYZ_r); xyY_g = colour.XYZ_to_xyY(XYZ_g); xyY_b = colour.XYZ_to_xyY(XYZ_b); print(xyY_r) print(xyY_g) print(xyY_b)
def HEX_2_XYY(hex): return colour.XYZ_to_xyY( colour.sRGB_to_XYZ(colour.notation.HEX_to_RGB(hex)))
variables["D50XYZ_OCIO"]).flatten() print(variables) # Perform test. Convert a D65 sRGB value to D50 Apple P3. AppleCATD50toD65 = numpy.asarray(variables["chad"]) AppleP3_D50RGB_to_XYZ = numpy.asarray(variables["D50XYZ"]) AppleP3_D65RGB_to_XYZ = numpy.matmul( numpy.linalg.inv(AppleCATD50toD65), AppleP3_D50RGB_to_XYZ ) AppleWhite50XYZ = numpy.matmul(variables["D50XYZ"], [1., 1., 1.]) print("AppleWhite50 xyY:\n" + str(colour.XYZ_to_xyY( AppleWhite50XYZ, [0.3127, 0.3290])) + ", XYZ: " + str(AppleWhite50XYZ)) colour_AppleCATD50toD65 = ( colour.adaptation.chromatic_adaptation_matrix_VonKries( AppleWhite50XYZ, colour.xyY_to_XYZ([0.3127, 0.3290, 1.]), transform=u"Bradford" ) ) print("Apple D50 to D65 CAT:\n" + str(colour_AppleCATD50toD65)) sRGB = colour.models.sRGB_COLOURSPACE sRGB.use_derived_RGB_to_XYZ_matrix = True sRGB.use_derived_XYZ_to_RGB_matrix = True
""" Showcases colour models computations. """ import numpy as np import colour from colour.utilities import message_box message_box('Colour Models Computations') XYZ = np.array([0.20654008, 0.12197225, 0.05136952]) message_box(('Converting to "CIE xyY" colourspace from given "CIE XYZ" ' 'tristimulus values:\n' '\n\t{0}'.format(XYZ))) print(colour.XYZ_to_xyY(XYZ)) print('\n') message_box(('The default illuminant if X == Y == Z == 0 is ' '"CIE Standard Illuminant D Series D65".')) print(colour.XYZ_to_xyY(np.array([0.00000000, 0.00000000, 0.00000000]))) print('\n') message_box('Using an alternative illuminant.') print( colour.XYZ_to_xyY( np.array([0.00000000, 0.00000000, 0.00000000]), colour.ILLUMINANTS['CIE 1931 2 Degree Standard Observer']['ACES'], ))
'80% gray', '60% gray', '40% gray', '20% gray', 'card white', 'primary blue', 'primary green', 'primary red', 'primary yellow', 'primary magenta', 'primary cyan', 'sunflower', 'apple green', 'violet', 'pink', 'blueprint', 'primary orange', 'classic dark skin', 'classic light skin', 'steel blue', 'evergreen', 'lavender', 'aqua' ] data = OrderedDict(zip(names, colour.XYZ_to_xyY( colour.sRGB_to_XYZ(checker_swatches_sRGB)))) D65 = colour.ILLUMINANTS['CIE 1931 2 Degree Standard Observer']['D65'] colour_checker = colour.characterisation.ColourChecker( 'SpyderCHECKR 24', data, D65)
"""Showcases colour models computations.""" import numpy as np import colour from colour.utilities import message_box message_box("Colour Models Computations") XYZ = np.array([0.20654008, 0.12197225, 0.05136952]) message_box(f'Converting to the "CIE xyY" colourspace from given "CIE XYZ" ' f"tristimulus values:\n\n\t{XYZ}") print(colour.XYZ_to_xyY(XYZ)) print("\n") message_box("The default illuminant if X == Y == Z == 0 is " '"CIE Standard Illuminant D Series D65".') print(colour.XYZ_to_xyY(np.array([0.00000000, 0.00000000, 0.00000000]))) print("\n") message_box("Using an alternative illuminant.") print( colour.XYZ_to_xyY( np.array([0.00000000, 0.00000000, 0.00000000]), colour.CCS_ILLUMINANTS["CIE 1931 2 Degree Standard Observer"]["ACES"], )) print("\n")
def rgb_to_xybri(rgb): # TODO: make this use something other than D65 x, y, Y = colour.XYZ_to_xyY(colour.sRGB_to_XYZ(rgb)) bri = int(Y**(1 / 2.2) * 254) return {'xy': [x, y], 'bri': bri}