Exemplo n.º 1
0
    def test_XYZ_to_RGB(self):
        """
        Tests :func:`colour.models.rgb.rgb_colourspace.XYZ_to_RGB` definition.
        """

        np.testing.assert_almost_equal(
            XYZ_to_RGB(
                np.array([0.21638819, 0.12570000, 0.03847493]),
                np.array([0.34570, 0.35850]), np.array([0.31270, 0.32900]),
                np.array([
                    [3.24062548, -1.53720797, -0.49862860],
                    [-0.96893071, 1.87575606, 0.04151752],
                    [0.05571012, -0.20402105, 1.05699594],
                ]), 'Bradford', oetf_sRGB),
            np.array([0.70556599, 0.19109268, 0.22340812]),
            decimal=7)

        np.testing.assert_almost_equal(
            XYZ_to_RGB(
                np.array([0.21638819, 0.12570000, 0.03847493]),
                np.array([0.34570, 0.35850]), np.array([0.31270, 0.32900]),
                np.array([
                    [3.24062548, -1.53720797, -0.49862860],
                    [-0.96893071, 1.87575606, 0.04151752],
                    [0.05571012, -0.20402105, 1.05699594],
                ]), None, oetf_sRGB),
            np.array([0.72794579, 0.18180021, 0.17951580]),
            decimal=7)

        np.testing.assert_almost_equal(
            XYZ_to_RGB(
                np.array([0.21638819, 0.12570000, 0.03847493]),
                np.array([0.34570, 0.35850]), np.array([0.32168, 0.33767]),
                np.array([
                    [1.04981102, 0.00000000, -0.00009748],
                    [-0.49590302, 1.37331305, 0.09824004],
                    [0.00000000, 0.00000000, 0.99125202],
                ])),
            np.array([0.21959099, 0.06985815, 0.04703704]),
            decimal=7)

        np.testing.assert_almost_equal(
            XYZ_to_RGB(
                np.array([0.21638819, 0.12570000, 0.03847493]),
                np.array([0.34570, 0.35850]),
                np.array([0.31270, 0.32900, 1.00000]),
                np.array([
                    [3.24062548, -1.53720797, -0.49862860],
                    [-0.96893071, 1.87575606, 0.04151752],
                    [0.05571012, -0.20402105, 1.05699594],
                ])),
            np.array([0.45620801, 0.03079991, 0.04091883]),
            decimal=7)
Exemplo n.º 2
0
def XYZ_to_RGB_Smits1999(XYZ: ArrayLike) -> NDArray:
    """
    Convert from *CIE XYZ* tristimulus values to *RGB* colourspace with
    conditions required by the current *Smits (1999)* method implementation.

    Parameters
    ----------
    XYZ
        *CIE XYZ* tristimulus values.

    Returns
    -------
    :class:`numpy.ndarray`
        *RGB* colour array.

    Examples
    --------
    >>> XYZ = np.array([0.21781186, 0.12541048, 0.04697113])
    >>> XYZ_to_RGB_Smits1999(XYZ)  # doctest: +ELLIPSIS
    array([ 0.4063959...,  0.0275289...,  0.0398219...])
    """

    return XYZ_to_RGB(
        XYZ,
        CCS_WHITEPOINT_SMITS1999,
        CCS_WHITEPOINT_SMITS1999,
        MATRIX_XYZ_TO_RGB_SMITS1999,
    )
Exemplo n.º 3
0
def XYZ_to_RGB_Smits1999(XYZ):
    """
    Convenient object to convert from *CIE XYZ* tristimulus values to *RGB*
    colourspace in conditions required by the current *Smits (1999)* method
    implementation.

    Parameters
    ----------
    XYZ : array_like
        *CIE XYZ* tristimulus values.

    Returns
    -------
    ndarray
        *RGB* colour array.

    Notes
    -----
    -   Input *CIE XYZ* tristimulus values are in domain [0, 1].

    Examples
    --------
    >>> XYZ = np.array([0.07049534, 0.10080000, 0.09558313])
    >>> XYZ_to_RGB_Smits1999(XYZ)  # doctest: +ELLIPSIS
    array([ 0.0214496...,  0.1315460...,  0.0928760...])
    """

    return XYZ_to_RGB(XYZ,
                      SMITS1999_WHITEPOINT,
                      SMITS1999_WHITEPOINT,
                      SMITS1999_XYZ_TO_RGB_MATRIX,
                      encoding_cctf=None)
Exemplo n.º 4
0
def XYZ_to_RGB_Smits1999(XYZ):
    """
    Convenient object to convert from *CIE XYZ* tristimulus values to *RGB*
    colourspace in conditions required by the current *Smits (1999)* method
    implementation.

    Parameters
    ----------
    XYZ : array_like
        *CIE XYZ* tristimulus values.

    Returns
    -------
    ndarray
        *RGB* colour array.

    Examples
    --------
    >>> XYZ = np.array([0.21781186, 0.12541048, 0.04697113])
    >>> XYZ_to_RGB_Smits1999(XYZ)  # doctest: +ELLIPSIS
    array([ 0.4063959...,  0.0275289...,  0.0398219...])
    """

    return XYZ_to_RGB(XYZ,
                      SMITS1999_WHITEPOINT,
                      SMITS1999_WHITEPOINT,
                      SMITS1999_XYZ_TO_RGB_MATRIX,
                      cctf_encoding=None)
Exemplo n.º 5
0
def RGB_colourspace_volume_coverage_MonteCarlo(
        colourspace,
        coverage_sampler,
        samples=10e6,
        random_generator=random_triplet_generator,
        random_state=None):
    """
    Returns given *RGB* colourspace percentage coverage of an arbitrary volume.

    Parameters
    ----------
    colourspace : RGB_Colourspace
        *RGB* colourspace to compute the volume coverage percentage.
    coverage_sampler : object
        Python object responsible for checking the volume coverage.
    samples : numeric, optional
        Samples count.
    random_generator : generator, optional
        Random triplet generator providing the random samples.
    random_state : RandomState, optional
        Mersenne Twister pseudo-random number generator to use in the random
        number generator.

    Returns
    -------
    float
        Percentage coverage of volume.

    Examples
    --------
    >>> from colour import sRGB_COLOURSPACE as sRGB
    >>> prng = np.random.RandomState(2)
    >>> RGB_colourspace_volume_coverage_MonteCarlo(  # doctest: +ELLIPSIS
    ...     sRGB,
    ...     is_within_pointer_gamut,
    ...     10e3,
    ...     random_state=prng)
    83...
    """

    random_state = (random_state
                    if random_state is not None else
                    np.random.RandomState())

    # TODO: Investigate for generator yielding directly a ndarray.
    XYZ = np.asarray(list(random_generator(
        samples, random_state=random_state)))
    XYZ_vs = XYZ[coverage_sampler(XYZ)]

    RGB = XYZ_to_RGB(XYZ_vs,
                     colourspace.whitepoint,
                     colourspace.whitepoint,
                     colourspace.XYZ_to_RGB_matrix)

    RGB_c = RGB[np.logical_and(np.min(RGB, axis=-1) >= 0,
                               np.max(RGB, axis=-1) <= 1)]

    return 100 * RGB_c.size / XYZ_vs.size
Exemplo n.º 6
0
def RGB_colourspace_volume_coverage_MonteCarlo(
    colourspace: RGB_Colourspace,
    coverage_sampler: Callable,
    samples: Integer = 1000000,
    random_generator: Callable = random_triplet_generator,
    random_state: np.random.RandomState = None,
) -> Floating:
    """
    Return given *RGB* colourspace percentage coverage of an arbitrary volume.

    Parameters
    ----------
    colourspace
        *RGB* colourspace to compute the volume coverage percentage.
    coverage_sampler
        Python object responsible for checking the volume coverage.
    samples
        Samples count.
    random_generator
        Random triplet generator providing the random samples.
    random_state
        Mersenne Twister pseudo-random number generator to use in the random
        number generator.

    Returns
    -------
    :class:`numpy.floating`
        Percentage coverage of volume.

    Examples
    --------
    >>> from colour.models import RGB_COLOURSPACE_sRGB as sRGB
    >>> prng = np.random.RandomState(2)
    >>> RGB_colourspace_volume_coverage_MonteCarlo(
    ...     sRGB, is_within_pointer_gamut, 10e3, random_state=prng)
    ... # doctest: +ELLIPSIS
    81...
    """

    random_state = (random_state
                    if random_state is not None else np.random.RandomState())

    XYZ = random_generator(DEFAULT_INT_DTYPE(samples),
                           random_state=random_state)
    XYZ_vs = XYZ[coverage_sampler(XYZ)]

    RGB = XYZ_to_RGB(
        XYZ_vs,
        colourspace.whitepoint,
        colourspace.whitepoint,
        colourspace.matrix_XYZ_to_RGB,
    )

    RGB_c = RGB[np.logical_and(
        np.min(RGB, axis=-1) >= 0,
        np.max(RGB, axis=-1) <= 1)]

    return 100 * RGB_c.size / XYZ_vs.size
Exemplo n.º 7
0
    def test_XYZ_to_RGB(self):
        """
        Tests :func:`colour.models.rgb.rgb_colourspace.XYZ_to_RGB` definition.
        """

        np.testing.assert_almost_equal(
            XYZ_to_RGB(
                np.array([0.11518475, 0.10080000, 0.05089373]),
                np.array([0.34570, 0.35850]),
                np.array([0.31270, 0.32900]),
                np.array([
                    [3.24062548, -1.53720797, -0.49862860],
                    [-0.96893071, 1.87575606, 0.04151752],
                    [0.05571012, -0.20402105, 1.05699594],
                ]), 'Bradford', oetf_sRGB),
            np.array([0.45286611, 0.31735742, 0.26418007]),
            decimal=7)

        np.testing.assert_almost_equal(
            XYZ_to_RGB(
                np.array([0.11518475, 0.10080000, 0.05089373]),
                np.array([0.34570, 0.35850]),
                np.array([0.32168, 0.33767]),
                np.array([
                    [1.04981102, 0.00000000, -0.00009748],
                    [-0.49590302, 1.37331305, 0.09824004],
                    [0.00000000, 0.00000000, 0.99125202],
                ])),
            np.array([0.11757966, 0.08781514, 0.06185473]),
            decimal=7)

        np.testing.assert_almost_equal(
            XYZ_to_RGB(
                np.array([0.07049534, 0.10080000, 0.09558313]),
                np.array([0.34570, 0.35850]),
                np.array([0.31270, 0.32900, 0.10080]),
                np.array([
                    [3.24062548, -1.53720797, -0.49862860],
                    [-0.96893071, 1.87575606, 0.04151752],
                    [0.05571012, -0.20402105, 1.05699594],
                ])),
            np.array([0.00109657, 0.01282168, 0.01173596]),
            decimal=7)
Exemplo n.º 8
0
    def test_n_dimensional_XYZ_to_RGB(self):
        """
        Tests :func:`colour.models.rgb.rgb_colourspace.XYZ_to_RGB` definition
        n-dimensions support.
        """

        XYZ = np.array([0.21638819, 0.12570000, 0.03847493])
        W_R = np.array([0.34570, 0.35850])
        W_T = np.array([0.31270, 0.32900])
        M = np.array([
            [3.24062548, -1.53720797, -0.49862860],
            [-0.96893071, 1.87575606, 0.04151752],
            [0.05571012, -0.20402105, 1.05699594],
        ])
        RGB = np.array([0.70556599, 0.19109268, 0.22340812])
        np.testing.assert_almost_equal(XYZ_to_RGB(XYZ, W_R, W_T, M, 'Bradford',
                                                  oetf_sRGB),
                                       RGB,
                                       decimal=7)

        XYZ = np.tile(XYZ, (6, 1))
        RGB = np.tile(RGB, (6, 1))
        np.testing.assert_almost_equal(XYZ_to_RGB(XYZ, W_R, W_T, M, 'Bradford',
                                                  oetf_sRGB),
                                       RGB,
                                       decimal=7)

        W_R = np.tile(W_R, (6, 1))
        W_T = np.tile(W_T, (6, 1))
        np.testing.assert_almost_equal(XYZ_to_RGB(XYZ, W_R, W_T, M, 'Bradford',
                                                  oetf_sRGB),
                                       RGB,
                                       decimal=7)

        XYZ = np.reshape(XYZ, (2, 3, 3))
        W_R = np.reshape(W_R, (2, 3, 2))
        W_T = np.reshape(W_T, (2, 3, 2))
        RGB = np.reshape(RGB, (2, 3, 3))
        np.testing.assert_almost_equal(XYZ_to_RGB(XYZ, W_R, W_T, M, 'Bradford',
                                                  oetf_sRGB),
                                       RGB,
                                       decimal=7)
Exemplo n.º 9
0
    def test_n_dimensional_XYZ_to_RGB(self):
        """
        Tests :func:`colour.models.rgb.rgb_colourspace.XYZ_to_RGB` definition
        n-dimensions support.
        """

        XYZ = np.array([0.07049534, 0.10080000, 0.09558313])
        W_R = np.array([0.34570, 0.35850])
        W_T = np.array([0.31270, 0.32900])
        M = np.array([[3.24062548, -1.53720797, -0.49862860],
                      [-0.96893071, 1.87575606, 0.04151752],
                      [0.05571012, -0.20402105, 1.05699594]])
        RGB = np.array([0.01087863, 0.12719923, 0.11642816])
        np.testing.assert_almost_equal(
            XYZ_to_RGB(XYZ, W_R, W_T, M),
            RGB,
            decimal=7)

        XYZ = np.tile(XYZ, (6, 1))
        RGB = np.tile(RGB, (6, 1))
        np.testing.assert_almost_equal(
            XYZ_to_RGB(XYZ, W_R, W_T, M),
            RGB,
            decimal=7)

        W_R = np.tile(W_R, (6, 1))
        W_T = np.tile(W_T, (6, 1))
        np.testing.assert_almost_equal(
            XYZ_to_RGB(XYZ, W_R, W_T, M),
            RGB,
            decimal=7)

        XYZ = np.reshape(XYZ, (2, 3, 3))
        W_R = np.reshape(W_R, (2, 3, 2))
        W_T = np.reshape(W_T, (2, 3, 2))
        RGB = np.reshape(RGB, (2, 3, 3))
        np.testing.assert_almost_equal(
            XYZ_to_RGB(XYZ, W_R, W_T, M),
            RGB,
            decimal=7)
Exemplo n.º 10
0
    def test_nan_XYZ_to_RGB(self):
        """
        Tests :func:`colour.models.rgb.XYZ_to_RGB` definition nan support.
        """

        cases = [-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan]
        cases = set(permutations(cases * 3, r=3))
        for case in cases:
            XYZ = np.array(case)
            W_R = np.array(case[0:2])
            W_T = np.array(case[0:2])
            M = np.vstack((case, case, case)).reshape((3, 3))
            XYZ_to_RGB(XYZ, W_R, W_T, M)
Exemplo n.º 11
0
def XYZ_to_plotting_colourspace(
    XYZ: ArrayLike,
    illuminant: ArrayLike = RGB_COLOURSPACES["sRGB"].whitepoint,
    chromatic_adaptation_transform: Union[Literal["Bianco 2010",
                                                  "Bianco PC 2010", "Bradford",
                                                  "CAT02 Brill 2008", "CAT02",
                                                  "CAT16", "CMCCAT2000",
                                                  "CMCCAT97", "Fairchild",
                                                  "Sharp", "Von Kries",
                                                  "XYZ Scaling", ],
                                          str, ] = "CAT02",
    apply_cctf_encoding: Boolean = True,
) -> NDArray:
    """
    Convert from *CIE XYZ* tristimulus values to the default plotting
    colourspace.

    Parameters
    ----------
    XYZ
        *CIE XYZ* tristimulus values.
    illuminant
        Source illuminant chromaticity coordinates.
    chromatic_adaptation_transform
        *Chromatic adaptation* transform.
    apply_cctf_encoding
        Apply the default plotting colourspace encoding colour component
        transfer function / opto-electronic transfer function.

    Returns
    -------
    :class:`numpy.ndarray`
        Default plotting colourspace colour array.

    Examples
    --------
    >>> import numpy as np
    >>> XYZ = np.array([0.20654008, 0.12197225, 0.05136952])
    >>> XYZ_to_plotting_colourspace(XYZ)  # doctest: +ELLIPSIS
    array([ 0.7057393...,  0.1924826...,  0.2235416...])
    """

    return XYZ_to_RGB(
        XYZ,
        illuminant,
        CONSTANTS_COLOUR_STYLE.colour.colourspace.whitepoint,
        CONSTANTS_COLOUR_STYLE.colour.colourspace.matrix_XYZ_to_RGB,
        chromatic_adaptation_transform,
        CONSTANTS_COLOUR_STYLE.colour.colourspace.cctf_encoding
        if apply_cctf_encoding else None,
    )
Exemplo n.º 12
0
    def test_domain_range_scale_XYZ_to_RGB(self):
        """
        Tests :func:`colour.models.rgb.rgb_colourspace.XYZ_to_RGB` definition
        domain and range scale support.
        """

        XYZ = np.array([0.21638819, 0.12570000, 0.03847493])
        W_R = np.array([0.34570, 0.35850])
        W_T = np.array([0.31270, 0.32900])
        M = np.array([
            [3.24062548, -1.53720797, -0.49862860],
            [-0.96893071, 1.87575606, 0.04151752],
            [0.05571012, -0.20402105, 1.05699594],
        ])
        RGB = XYZ_to_RGB(XYZ, W_R, W_T, M)

        d_r = (('reference', 1), (1, 1), (100, 100))
        for scale, factor in d_r:
            with domain_range_scale(scale):
                np.testing.assert_almost_equal(XYZ_to_RGB(
                    XYZ * factor, W_R, W_T, M),
                                               RGB * factor,
                                               decimal=7)
Exemplo n.º 13
0
def xy_to_rgb(xy, name='ITU-R BT.2020', normalize='maximum', specific=None):
    """
    xy値からRGB値を算出する。
    いい感じに正規化もしておく。

    Parameters
    ----------
    xy : array_like
        xy value.
    name : string
        color space name.
    normalize : string
        normalize method. You can select 'maximum', 'specific' or None.

    Returns
    -------
    array_like
        rgb value. the value is normalized.
    """
    illuminant_XYZ = D65_WHITE
    illuminant_RGB = D65_WHITE
    chromatic_adaptation_transform = 'CAT02'
    large_xyz_to_rgb_matrix = get_xyz_to_rgb_matrix(name)
    if normalize == 'specific':
        xyY = xy_to_xyY(xy)
        xyY[..., 2] = specific
        large_xyz = xyY_to_XYZ(xyY)
    else:
        large_xyz = xy_to_XYZ(xy)

    rgb = XYZ_to_RGB(large_xyz, illuminant_XYZ, illuminant_RGB,
                     large_xyz_to_rgb_matrix,
                     chromatic_adaptation_transform)

    """
    そのままだとビデオレベルが低かったりするので、
    各ドット毎にRGB値を正規化&最大化する。必要であれば。
    """
    if normalize == 'maximum':
        rgb = normalise_maximum(rgb, axis=-1)
    else:
        if(np.sum(rgb > 1.0) > 0):
            print("warning: over flow has occured at xy_to_rgb")
        if(np.sum(rgb < 0.0) > 0):
            print("warning: under flow has occured at xy_to_rgb")
        rgb[rgb < 0] = 0
        rgb[rgb > 1.0] = 1.0

    return rgb
Exemplo n.º 14
0
    def test_n_dimensional_XYZ_to_RGB(self):
        """
        Tests :func:`colour.models.rgb.XYZ_to_RGB` definition n-dimensions
        support.
        """

        XYZ = np.array([0.07049534, 0.10080000, 0.09558313])
        W_R = np.array([0.34567, 0.35850])
        W_T = np.array([0.31271, 0.32902])
        M = np.array([[3.24100326, -1.53739899, -0.49861587],
                      [-0.96922426, 1.87592999, 0.04155422],
                      [0.05563942, -0.20401120, 1.05714897]])
        RGB = np.array([0.01091381, 0.12719366, 0.11641136])
        np.testing.assert_almost_equal(XYZ_to_RGB(XYZ, W_R, W_T, M),
                                       RGB,
                                       decimal=7)

        XYZ = np.tile(XYZ, (6, 1))
        RGB = np.tile(RGB, (6, 1))
        np.testing.assert_almost_equal(XYZ_to_RGB(XYZ, W_R, W_T, M),
                                       RGB,
                                       decimal=7)

        W_R = np.tile(W_R, (6, 1))
        W_T = np.tile(W_T, (6, 1))
        np.testing.assert_almost_equal(XYZ_to_RGB(XYZ, W_R, W_T, M),
                                       RGB,
                                       decimal=7)

        XYZ = np.reshape(XYZ, (2, 3, 3))
        W_R = np.reshape(W_R, (2, 3, 2))
        W_T = np.reshape(W_T, (2, 3, 2))
        RGB = np.reshape(RGB, (2, 3, 3))
        np.testing.assert_almost_equal(XYZ_to_RGB(XYZ, W_R, W_T, M),
                                       RGB,
                                       decimal=7)
Exemplo n.º 15
0
    def test_XYZ_to_RGB(self):
        """
        Tests :func:`colour.models.rgb.XYZ_to_RGB` definition.
        """

        for _xyY, XYZ, RGB in sRGB_LINEAR_COLORCHECKER_2005:
            np.testing.assert_almost_equal(XYZ_to_RGB(
                np.array(XYZ), np.array([0.34567, 0.35850]),
                np.array([0.31271, 0.32902]),
                np.array([[3.24100326, -1.53739899, -0.49861587],
                          [-0.96922426, 1.87592999, 0.04155422],
                          [0.05563942, -0.20401120, 1.05714897]]), 'Bradford',
                sRGB_OECF),
                                           RGB,
                                           decimal=7)

        for _xyY, XYZ, RGB in ACES_COLORCHECKER_2005:
            np.testing.assert_almost_equal(XYZ_to_RGB(
                np.array(XYZ), np.array([0.34567, 0.35850]),
                np.array([0.32168, 0.33767]),
                np.array([[1.04981102e+00, 0.00000000e+00, -9.74845410e-05],
                          [-4.95903023e-01, 1.37331305e+00, 9.82400365e-02],
                          [0.00000000e+00, 0.00000000e+00, 9.91252022e-01]])),
                                           RGB,
                                           decimal=7)

        XYZ = np.array([0.07049534, 0.10080000, 0.09558313])
        W_R = np.array([0.34567, 0.35850])
        W_T = np.array([0.31271, 0.32902, 0.10080])
        M = np.array([[3.24100326, -1.53739899, -0.49861587],
                      [-0.96922426, 1.87592999, 0.04155422],
                      [0.05563942, -0.20401120, 1.05714897]])
        np.testing.assert_almost_equal(
            XYZ_to_RGB(XYZ, W_R, W_T, M),
            np.array([0.00110011, 0.01282112, 0.01173427]),
            decimal=7)
Exemplo n.º 16
0
def XYZ_to_plotting_colourspace(XYZ,
                                illuminant=RGB_COLOURSPACES['sRGB'].whitepoint,
                                chromatic_adaptation_transform='CAT02',
                                apply_encoding_cctf=True):
    """
    Converts from *CIE XYZ* tristimulus values to
    :attr:`colour.plotting.DEFAULT_PLOTTING_COLOURSPACE` colourspace.

    Parameters
    ----------
    XYZ : array_like
        *CIE XYZ* tristimulus values.
    illuminant : array_like, optional
        Source illuminant chromaticity coordinates.
    chromatic_adaptation_transform : unicode, optional
        **{'CAT02', 'XYZ Scaling', 'Von Kries', 'Bradford', 'Sharp',
        'Fairchild', 'CMCCAT97', 'CMCCAT2000', 'CAT02_BRILL_CAT', 'Bianco',
        'Bianco PC'}**,
        *Chromatic adaptation* transform.
    apply_encoding_cctf : bool, optional
        Apply :attr:`colour.plotting.DEFAULT_PLOTTING_COLOURSPACE` colourspace
        encoding colour component transfer function / opto-electronic transfer
        function.

    Returns
    -------
    ndarray
        :attr:`colour.plotting.DEFAULT_PLOTTING_COLOURSPACE` colourspace colour
        array.

    Examples
    --------
    >>> import numpy as np
    >>> XYZ = np.array([0.20654008, 0.12197225, 0.05136952])
    >>> XYZ_to_plotting_colourspace(XYZ)  # doctest: +ELLIPSIS
    array([ 0.7057393...,  0.1924826...,  0.2235416...])
    """

    return XYZ_to_RGB(
        XYZ, illuminant, COLOUR_STYLE_CONSTANTS.colour.colourspace.whitepoint,
        COLOUR_STYLE_CONSTANTS.colour.colourspace.XYZ_to_RGB_matrix,
        chromatic_adaptation_transform,
        COLOUR_STYLE_CONSTANTS.colour.colourspace.encoding_cctf
        if apply_encoding_cctf else None)
Exemplo n.º 17
0
    def check_basis_functions(self):
        """
        Test :func:`colour.recovery.RGB_to_sd_Mallett2019` definition or the
        more specialised :func:`colour.recovery.RGB_to_sd_Mallett2019`
        definition.
        """

        # Make sure the white point is reconstructed as a perfectly flat
        # spectrum.
        RGB = np.full(3, 1.0)
        sd = RGB_to_sd_Mallett2019(RGB, self._basis)
        self.assertLess(np.var(sd.values), 1e-5)

        # Check if the primaries or their combination exceeds the [0, 1] range.
        lower = np.zeros_like(sd.values) - 1e-12
        upper = np.ones_like(sd.values) + 1e12
        for RGB in [[1, 1, 1], [1, 0, 0], [0, 1, 0], [0, 0, 1]]:
            sd = RGB_to_sd_Mallett2019(RGB, self._basis)
            np.testing.assert_array_less(sd.values, upper)
            np.testing.assert_array_less(lower, sd.values)

        # Check Delta E's using a colour checker.
        for name, sd in SDS_COLOURCHECKERS["ColorChecker N Ohta"].items():
            XYZ = sd_to_XYZ(sd, self._cmfs, self._sd_D65) / 100
            Lab = XYZ_to_Lab(XYZ, self._xy_D65)
            RGB = XYZ_to_RGB(
                XYZ,
                self._RGB_colourspace.whitepoint,
                self._xy_D65,
                self._RGB_colourspace.matrix_XYZ_to_RGB,
            )

            recovered_sd = RGB_to_sd_Mallett2019(RGB, self._basis)
            recovered_XYZ = (
                sd_to_XYZ(recovered_sd, self._cmfs, self._sd_D65) / 100
            )
            recovered_Lab = XYZ_to_Lab(recovered_XYZ, self._xy_D65)

            error = delta_E_CIE1976(Lab, recovered_Lab)

            if error > 4 * JND_CIE1976 / 100:  # pragma: no cover
                self.fail(f'Delta E for "{name}" is {error}!')
Exemplo n.º 18
0
def highlights_recovery_LCHab(RGB,
                              threshold=None,
                              RGB_colourspace=sRGB_COLOURSPACE):
    """
    Performs highlights recovery in *CIE L\\*C\\*Hab* colourspace.

    Parameters
    ----------
    RGB : array_like
        *RGB* colourspace array.
    threshold : numeric, optional
        Threshold for highlights selection, automatically computed
        if not given.
    RGB_colourspace : RGB_Colourspace, optional
        Working *RGB* colourspace to perform the *CIE L\\*C\\*Hab* to and from.

    Returns
    -------
    ndarray
         Highlights recovered *RGB* colourspace array.
    """

    L, _C, H = tsplit(
        Lab_to_LCHab(
            XYZ_to_Lab(
                RGB_to_XYZ(RGB, RGB_colourspace.whitepoint,
                           RGB_colourspace.whitepoint,
                           RGB_colourspace.RGB_to_XYZ_matrix),
                RGB_colourspace.whitepoint)))
    _L_c, C_c, _H_c = tsplit(
        Lab_to_LCHab(
            XYZ_to_Lab(
                RGB_to_XYZ(np.clip(RGB, 0,
                                   threshold), RGB_colourspace.whitepoint,
                           RGB_colourspace.whitepoint,
                           RGB_colourspace.RGB_to_XYZ_matrix),
                RGB_colourspace.whitepoint)))

    return XYZ_to_RGB(
        Lab_to_XYZ(LCHab_to_Lab(tstack([L, C_c, H])),
                   RGB_colourspace.whitepoint), RGB_colourspace.whitepoint,
        RGB_colourspace.whitepoint, RGB_colourspace.XYZ_to_RGB_matrix)
Exemplo n.º 19
0
def XYZ_to_sRGB(XYZ,
                illuminant=RGB_COLOURSPACES.get('sRGB').whitepoint,
                chromatic_adaptation_transform='CAT02',
                apply_OECF=True):
    """
    Converts from *CIE XYZ* tristimulus values to *sRGB* colourspace.

    Parameters
    ----------
    XYZ : array_like
        *CIE XYZ* tristimulus values.
    illuminant : array_like, optional
        Source illuminant chromaticity coordinates.
    chromatic_adaptation_transform : unicode, optional
        **{'CAT02', 'XYZ Scaling', 'Von Kries', 'Bradford', 'Sharp',
        'Fairchild, 'CMCCAT97', 'CMCCAT2000', 'CAT02_BRILL_CAT', 'Bianco',
        'Bianco PC'}**,
        *Chromatic adaptation* transform.
    apply_OECF : bool, optional
        Apply *sRGB* *opto-electronic conversion function*.

    Returns
    -------
    ndarray
        *sRGB* colour array.

    Notes
    -----
    -   Input *CIE XYZ* tristimulus values are in domain [0, 1].

    Examples
    --------
    >>> import numpy as np
    >>> XYZ = np.array([0.07049534, 0.10080000, 0.09558313])
    >>> XYZ_to_sRGB(XYZ)  # doctest: +ELLIPSIS
    array([ 0.1750135...,  0.3881879...,  0.3216195...])
    """

    sRGB = RGB_COLOURSPACES.get('sRGB')
    return XYZ_to_RGB(XYZ, illuminant, sRGB.whitepoint, sRGB.XYZ_to_RGB_matrix,
                      chromatic_adaptation_transform,
                      sRGB.OECF if apply_OECF else None)
Exemplo n.º 20
0
def XYZ_to_sRGB(XYZ,
                illuminant=RGB_COLOURSPACES.get('sRGB').whitepoint,
                chromatic_adaptation_method='CAT02',
                transfer_function=True):
    """
    Converts from *CIE XYZ* colourspace to *sRGB* colourspace.

    Parameters
    ----------
    XYZ : array_like, (3,)
        *CIE XYZ* colourspace matrix.
    illuminant : array_like, optional
        Source illuminant chromaticity coordinates.
    chromatic_adaptation_method : unicode, optional
        ('XYZ Scaling', 'Bradford', 'Von Kries', 'Fairchild', 'CAT02')
        *Chromatic adaptation* method.
    transfer_function : bool, optional
        Apply *sRGB* *transfer function*.

    Returns
    -------
    ndarray, (3,)
        *sRGB* colour matrix.

    Notes
    -----
    -   Input *CIE XYZ* colourspace matrix is in domain [0, 1].

    Examples
    --------
    >>> XYZ = np.array([0.1180583421, 0.1034, 0.0515089229])
    >>> XYZ_to_sRGB(XYZ)  # doctest: +ELLIPSIS
    array([ 0.4822488...,  0.3165197...,  0.2207051...])
    """

    sRGB = RGB_COLOURSPACES.get('sRGB')
    return XYZ_to_RGB(XYZ, illuminant, sRGB.whitepoint, sRGB.to_RGB,
                      chromatic_adaptation_method,
                      sRGB.transfer_function if transfer_function else None)
Exemplo n.º 21
0
def XYZ_to_RGB_Smits1999(XYZ, chromatic_adaptation_transform='Bradford'):
    """
    Convenient object to convert from *CIE XYZ* tristimulus values to *RGB*
    colourspace in conditions required by the current *Smits (1999)* method
    implementation.

    Parameters
    ----------
    XYZ : array_like
        *CIE XYZ* tristimulus values.
    chromatic_adaptation_transform : unicode, optional
        **{'CAT02', 'XYZ Scaling', 'Von Kries', 'Bradford', 'Sharp',
        'Fairchild', 'CMCCAT97', 'CMCCAT2000', 'CAT02_BRILL_CAT', 'Bianco',
        'Bianco PC'}**,
        *Chromatic adaptation* method.

    Returns
    -------
    ndarray
        *RGB* colour array.

    Notes
    -----
    -   Input *CIE XYZ* tristimulus values are in domain [0, 1].

    Examples
    --------
    >>> XYZ = np.array([0.07049534, 0.10080000, 0.09558313])
    >>> XYZ_to_RGB_Smits1999(XYZ)  # doctest: +ELLIPSIS
    array([ 0.0214496...,  0.1315460...,  0.0928760...])
    """

    return XYZ_to_RGB(
        XYZ,
        SMITS1999_WHITEPOINT,
        SMITS1999_WHITEPOINT,
        SMITS1999_XYZ_TO_RGB_MATRIX,
        chromatic_adaptation_transform,
        encoding_cctf=None)
Exemplo n.º 22
0
def sample_RGB_colourspace_volume_MonteCarlo(
        colourspace,
        samples=10e6,
        limits=np.array([[0, 100], [-150, 150], [-150, 150]]),
        illuminant_Lab=ILLUMINANTS['CIE 1931 2 Degree Standard Observer']
    ['D65'],
        chromatic_adaptation_method='CAT02',
        random_generator=random_triplet_generator,
        random_state=None):
    """
    Randomly samples the *Lab* colourspace volume and returns the ratio of
    samples within the given *RGB* colourspace volume.

    Parameters
    ----------
    colourspace : RGB_Colourspace
        *RGB* colourspace to compute the volume of.
    samples : numeric, optional
        Samples count.
    limits : array_like, optional
        *Lab* colourspace volume.
    illuminant_Lab : array_like, optional
        *Lab* colourspace *illuminant* chromaticity coordinates.
    chromatic_adaptation_method : unicode, optional
        **{'CAT02', 'XYZ Scaling', 'Von Kries', 'Bradford', 'Sharp',
        'Fairchild', 'CMCCAT97', 'CMCCAT2000', 'CAT02_BRILL_CAT', 'Bianco',
        'Bianco PC'}**,
        *Chromatic adaptation* method.
    random_generator : generator, optional
        Random triplet generator providing the random samples within the *Lab*
        colourspace volume.
    random_state : RandomState, optional
        Mersenne Twister pseudo-random number generator to use in the random
        number generator.

    Returns
    -------
    integer
        Within *RGB* colourspace volume samples count.

    Notes
    -----
    -   The doctest is assuming that :func:`np.random.RandomState` definition
        will return the same sequence no matter which *OS* or *Python*
        version is used. There is however no formal promise about the *prng*
        sequence reproducibility of either *Python* or *Numpy*
        implementations: Laurent. (2012). Reproducibility of python
        pseudo-random numbers across systems and versions? Retrieved January
        20, 2015, from http://stackoverflow.com/questions/8786084/\
reproducibility-of-python-pseudo-random-numbers-across-systems-and-versions

    Examples
    --------
    >>> from colour.models import sRGB_COLOURSPACE as sRGB
    >>> prng = np.random.RandomState(2)
    >>> sample_RGB_colourspace_volume_MonteCarlo(sRGB, 10e3, random_state=prng)
    ... # doctest: +ELLIPSIS
    9...
    """

    random_state = (random_state
                    if random_state is not None else np.random.RandomState())

    Lab = as_float_array(list(random_generator(samples, limits, random_state)))
    RGB = XYZ_to_RGB(
        Lab_to_XYZ(Lab, illuminant_Lab),
        illuminant_Lab,
        colourspace.whitepoint,
        colourspace.XYZ_to_RGB_matrix,
        chromatic_adaptation_transform=chromatic_adaptation_method)
    RGB_w = RGB[np.logical_and(
        np.min(RGB, axis=-1) >= 0,
        np.max(RGB, axis=-1) <= 1)]
    return len(RGB_w)
Exemplo n.º 23
0
def plot_xyY_color_space(name='ITU-R BT.2020', samples=1024,
                         antialiasing=True):
    """
    SONY の HDR説明資料にあるような xyY の図を作る。

    Parameters
    ----------
    name : str
        name of the target color space.

    Returns
    -------
    None

    """

    # 馬蹄の領域判別用データ作成
    # --------------------------
    primary_xy, _ = get_primaries(name=name)
    triangulation = Delaunay(primary_xy)

    xx, yy\
        = np.meshgrid(np.linspace(0, 1, samples), np.linspace(1, 0, samples))
    xy = np.dstack((xx, yy))
    mask = (triangulation.find_simplex(xy) < 0).astype(np.float)

    # アンチエイリアシングしてアルファチャンネルを滑らかに
    # ------------------------------------------------
    if antialiasing:
        kernel = np.array([
            [0, 1, 0],
            [1, 2, 1],
            [0, 1, 0],
        ]).astype(np.float)
        kernel /= np.sum(kernel)
        mask = convolve(mask, kernel)

    # ネガポジ反転
    # --------------------------------
    mask = 1 - mask[:, :, np.newaxis]

    # xy のメッシュから色を復元
    # ------------------------
    illuminant_XYZ = D65_WHITE
    illuminant_RGB = RGB_COLOURSPACES[name].whitepoint
    chromatic_adaptation_transform = 'CAT02'
    large_xyz_to_rgb_matrix = get_xyz_to_rgb_matrix(name)
    rgb_to_large_xyz_matrix = get_rgb_to_xyz_matrix(name)
    large_xyz = xy_to_XYZ(xy)
    rgb = XYZ_to_RGB(large_xyz, illuminant_XYZ, illuminant_RGB,
                     large_xyz_to_rgb_matrix,
                     chromatic_adaptation_transform)

    """
    そのままだとビデオレベルが低かったりするので、
    各ドット毎にRGB値を正規化&最大化する。
    """
    rgb_org = normalise_maximum(rgb, axis=-1)

    # mask 適用
    # -------------------------------------
    mask_rgb = np.dstack((mask, mask, mask))
    rgb = rgb_org * mask_rgb
    rgba = np.dstack((rgb, mask))

    # こっからもういちど XYZ に変換。Yを求めるために。
    # ---------------------------------------------
    large_xyz2 = RGB_to_XYZ(rgb, illuminant_RGB, illuminant_XYZ,
                            rgb_to_large_xyz_matrix,
                            chromatic_adaptation_transform)

    # ログスケールに変換する準備
    # --------------------------
    large_y = large_xyz2[..., 1] * 1000
    large_y[large_y < 1] = 1.0

    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')
    # ax.plot_wireframe(xy[..., 0], xy[..., 1], np.log10(large_y),
    #                   rcount=100, ccount=100)
    ax.plot_surface(xy[..., 0], xy[..., 1], np.log10(large_y),
                    rcount=64, ccount=64, facecolors=rgb_org)
    ax.set_xlabel("x")
    ax.set_ylabel("y")
    ax.set_zlabel("Y")
    ax.set_zticks([0, 1, 2, 3])
    ax.set_zticklabels([1, 10, 100, 1000])

    # chromatcity_image の取得。z=0 の位置に貼り付ける
    # ----------------------------------------------
    cie1931_rgb = get_chromaticity_image(samples=samples, bg_color=0.0)

    alpha = np.zeros_like(cie1931_rgb[..., 0])
    rgb_sum = np.sum(cie1931_rgb, axis=-1)
    alpha[rgb_sum > 0.00001] = 1
    cie1931_rgb = np.dstack((cie1931_rgb[..., 0], cie1931_rgb[..., 1],
                             cie1931_rgb[..., 2], alpha))
    zz = np.zeros_like(xy[..., 0])
    ax.plot_surface(xy[..., 0], xy[..., 1], zz,
                    facecolors=cie1931_rgb)

    plt.show()
Exemplo n.º 24
0
def get_chromaticity_image(samples=1024, antialiasing=True, bg_color=0.9,
                           xmin=0.0, xmax=1.0, ymin=0.0, ymax=1.0):
    """
    xy色度図の馬蹄形の画像を生成する

    Returns
    -------
    ndarray
        rgb image.
    """

    """
    色域設定。sRGBだと狭くて少し変だったのでBT.2020に設定。
    若干色が薄くなるのが難点。暇があれば改良したい。
    """
    # color_space = models.BT2020_COLOURSPACE
    # color_space = models.S_GAMUT3_COLOURSPACE
    color_space = models.ACES_CG_COLOURSPACE

    # 馬蹄形のxy値を算出
    # --------------------------
    cmf_xy = _get_cmfs_xy()

    """
    馬蹄の内外の判別をするために三角形で領域分割する(ドロネー図を作成)。
    ドロネー図を作れば後は外積計算で領域の内外を判別できる(たぶん)。

    なお、作成したドロネー図は以下のコードでプロット可能。
    1点補足しておくと、```plt.triplot``` の第三引数は、
    第一、第二引数から三角形を作成するための **インデックス** のリスト
    になっている。[[0, 1, 2], [2, 4, 3], ...]的な。

    ```python
    plt.figure()
    plt.triplot(xy[:, 0], xy[:, 1], triangulation.simplices.copy(), '-o')
    plt.title('triplot of Delaunay triangulation')
    plt.show()
    ```
    """
    triangulation = Delaunay(cmf_xy)

    """
    ```triangulation.find_simplex()``` で xy がどのインデックスの領域か
    調べることができる。戻り値が ```-1``` の場合は領域に含まれないため、
    0以下のリストで領域判定の mask を作ることができる。
    """
    xx, yy\
        = np.meshgrid(np.linspace(xmin, xmax, samples),
                      np.linspace(ymax, ymin, samples))
    xy = np.dstack((xx, yy))
    mask = (triangulation.find_simplex(xy) < 0).astype(np.float)

    # アンチエイリアシングしてアルファチャンネルを滑らかに
    # ------------------------------------------------
    if antialiasing:
        kernel = np.array([
            [0, 1, 0],
            [1, 2, 1],
            [0, 1, 0],
        ]).astype(np.float)
        kernel /= np.sum(kernel)
        mask = convolve(mask, kernel)

    # ネガポジ反転
    # --------------------------------
    mask = 1 - mask[:, :, np.newaxis]

    # xy のメッシュから色を復元
    # ------------------------
    illuminant_XYZ = D65_WHITE
    illuminant_RGB = color_space.whitepoint
    chromatic_adaptation_transform = 'XYZ Scaling'
    large_xyz_to_rgb_matrix = color_space.XYZ_to_RGB_matrix
    large_xyz = xy_to_XYZ(xy)
    rgb = XYZ_to_RGB(large_xyz, illuminant_XYZ, illuminant_RGB,
                     large_xyz_to_rgb_matrix,
                     chromatic_adaptation_transform)

    """
    そのままだとビデオレベルが低かったりするので、
    各ドット毎にRGB値を正規化&最大化する。
    """
    rgb = normalise_maximum(rgb, axis=-1)

    # mask 適用
    # -------------------------------------
    mask_rgb = np.dstack((mask, mask, mask))
    rgb *= mask_rgb

    # 背景色をグレーに変更
    # -------------------------------------
    bg_rgb = np.ones_like(rgb)
    bg_rgb *= (1 - mask_rgb) * bg_color

    rgb += bg_rgb

    rgb = rgb ** (1/2.2)

    return rgb
Exemplo n.º 25
0
def sample_RGB_colourspace_volume_MonteCarlo(
    colourspace: RGB_Colourspace,
    samples: Integer = 1000000,
    limits: ArrayLike = np.array([[0, 100], [-150, 150], [-150, 150]]),
    illuminant_Lab: ArrayLike = CCS_ILLUMINANTS[
        "CIE 1931 2 Degree Standard Observer"]["D65"],
    chromatic_adaptation_transform: Union[Literal["Bianco 2010",
                                                  "Bianco PC 2010", "Bradford",
                                                  "CAT02 Brill 2008", "CAT02",
                                                  "CAT16", "CMCCAT2000",
                                                  "CMCCAT97", "Fairchild",
                                                  "Sharp", "Von Kries",
                                                  "XYZ Scaling", ],
                                          str, ] = "CAT02",
    random_generator: Callable = random_triplet_generator,
    random_state: np.random.RandomState = None,
) -> Integer:
    """
    Randomly sample the *CIE L\\*a\\*b\\** colourspace volume and returns the
    ratio of samples within the given *RGB* colourspace volume.

    Parameters
    ----------
    colourspace
        *RGB* colourspace to compute the volume of.
    samples
        Samples count.
    limits
        *CIE L\\*a\\*b\\** colourspace volume.
    illuminant_Lab
        *CIE L\\*a\\*b\\** colourspace *illuminant* chromaticity coordinates.
    chromatic_adaptation_transform
        *Chromatic adaptation* transform.
    random_generator
        Random triplet generator providing the random samples within the
        *CIE L\\*a\\*b\\** colourspace volume.
    random_state
        Mersenne Twister pseudo-random number generator to use in the random
        number generator.

    Returns
    -------
    :class:`numpy.integer`
        Within *RGB* colourspace volume samples count.

    Notes
    -----
    -   The doctest is assuming that :func:`np.random.RandomState` definition
        will return the same sequence no matter which *OS* or *Python*
        version is used. There is however no formal promise about the *prng*
        sequence reproducibility of either *Python* or *Numpy*
        implementations: Laurent. (2012). Reproducibility of python
        pseudo-random numbers across systems and versions? Retrieved January
        20, 2015, from http://stackoverflow.com/questions/8786084/\
reproducibility-of-python-pseudo-random-numbers-across-systems-and-versions

    Examples
    --------
    >>> from colour.models import RGB_COLOURSPACE_sRGB as sRGB
    >>> prng = np.random.RandomState(2)
    >>> sample_RGB_colourspace_volume_MonteCarlo(sRGB, 10e3, random_state=prng)
    ... # doctest: +ELLIPSIS
    9...
    """

    random_state = (random_state
                    if random_state is not None else np.random.RandomState())

    Lab = random_generator(DEFAULT_INT_DTYPE(samples), limits, random_state)
    RGB = XYZ_to_RGB(
        Lab_to_XYZ(Lab, illuminant_Lab),
        illuminant_Lab,
        colourspace.whitepoint,
        colourspace.matrix_XYZ_to_RGB,
        chromatic_adaptation_transform=chromatic_adaptation_transform,
    )
    RGB_w = RGB[np.logical_and(
        np.min(RGB, axis=-1) >= 0,
        np.max(RGB, axis=-1) <= 1)]
    return len(RGB_w)