예제 #1
0
    def test_n_dimensional_Lab_to_XYZ(self):
        """
        Tests :func:`colour.models.cie_lab.Lab_to_XYZ` definition n-dimensions
        support.
        """

        Lab = np.array([41.52787529, 52.63858304, 26.92317922])
        illuminant = np.array([0.31270, 0.32900])
        XYZ = np.array([0.20654008, 0.12197225, 0.05136952])
        np.testing.assert_almost_equal(Lab_to_XYZ(Lab, illuminant),
                                       XYZ,
                                       decimal=7)

        Lab = np.tile(Lab, (6, 1))
        XYZ = np.tile(XYZ, (6, 1))
        np.testing.assert_almost_equal(Lab_to_XYZ(Lab, illuminant),
                                       XYZ,
                                       decimal=7)

        illuminant = np.tile(illuminant, (6, 1))
        np.testing.assert_almost_equal(Lab_to_XYZ(Lab, illuminant),
                                       XYZ,
                                       decimal=7)

        Lab = np.reshape(Lab, (2, 3, 3))
        illuminant = np.reshape(illuminant, (2, 3, 2))
        XYZ = np.reshape(XYZ, (2, 3, 3))
        np.testing.assert_almost_equal(Lab_to_XYZ(Lab, illuminant),
                                       XYZ,
                                       decimal=7)
예제 #2
0
    def test_n_dimensional_Lab_to_XYZ(self):
        """
        Tests :func:`colour.models.cie_lab.Lab_to_XYZ` definition n-dimensions
        support.
        """

        Lab = np.array([37.98562910, -23.62907688, -4.41746615])
        illuminant = np.array([0.34570, 0.35850])
        XYZ = np.array([0.07049534, 0.10080000, 0.09558313])
        np.testing.assert_almost_equal(Lab_to_XYZ(Lab, illuminant),
                                       XYZ,
                                       decimal=7)

        Lab = np.tile(Lab, (6, 1))
        XYZ = np.tile(XYZ, (6, 1))
        np.testing.assert_almost_equal(Lab_to_XYZ(Lab, illuminant),
                                       XYZ,
                                       decimal=7)

        illuminant = np.tile(illuminant, (6, 1))
        np.testing.assert_almost_equal(Lab_to_XYZ(Lab, illuminant),
                                       XYZ,
                                       decimal=7)

        Lab = np.reshape(Lab, (2, 3, 3))
        illuminant = np.reshape(illuminant, (2, 3, 2))
        XYZ = np.reshape(XYZ, (2, 3, 3))
        np.testing.assert_almost_equal(Lab_to_XYZ(Lab, illuminant),
                                       XYZ,
                                       decimal=7)
예제 #3
0
def is_within_pointer_gamut(XYZ, tolerance=None):
    """
    Returns if given *CIE XYZ* tristimulus values are within Pointer's Gamut
    volume.

    Parameters
    ----------
    XYZ : array_like
        *CIE XYZ* tristimulus values.
    tolerance : numeric, optional
        Tolerance allowed in the inside-triangle check.

    Returns
    -------
    bool
        Is within Pointer's Gamut.

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

    Examples
    --------
    >>> import numpy as np
    >>> is_within_pointer_gamut(np.array([0.3205, 0.4131, 0.5100]))
    array(True, dtype=bool)
    >>> a = np.array([[0.3205, 0.4131, 0.5100], [0.0005, 0.0031, 0.0010]])
    >>> is_within_pointer_gamut(a)
    array([ True, False], dtype=bool)
    """

    XYZ_p = Lab_to_XYZ(
        LCHab_to_Lab(POINTER_GAMUT_DATA), POINTER_GAMUT_ILLUMINANT)

    return is_within_mesh_volume(XYZ, XYZ_p, tolerance)
예제 #4
0
파일: test_cie_lab.py 프로젝트: yixw/colour
    def test_domain_range_scale_Lab_to_XYZ(self):
        """
        Tests :func:`colour.models.cie_lab.Lab_to_XYZ` definition
        domain and range scale support.
        """

        Lab = np.array([41.52787529, 52.63858304, 26.92317922])
        illuminant = np.array([0.31270, 0.32900])
        XYZ = Lab_to_XYZ(Lab, illuminant)

        d_r = (('reference', 1, 1), (1, 0.01, 1), (100, 1, 100))
        for scale, factor_a, factor_b in d_r:
            with domain_range_scale(scale):
                np.testing.assert_almost_equal(
                    Lab_to_XYZ(Lab * factor_a, illuminant),
                    XYZ * factor_b,
                    decimal=7)
예제 #5
0
    def test_nan_Lab_to_XYZ(self):
        """Test :func:`colour.models.cie_lab.Lab_to_XYZ` 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:
            Lab = np.array(case)
            illuminant = np.array(case[0:2])
            Lab_to_XYZ(Lab, illuminant)
예제 #6
0
    def test_Lab_to_XYZ(self):
        """
        Tests :func:`colour.models.cie_lab.Lab_to_XYZ` definition.
        """

        np.testing.assert_almost_equal(Lab_to_XYZ(
            np.array([100, 0.83871284, -21.55579303])),
                                       np.array([0.96907232, 1., 1.12179215]),
                                       decimal=7)

        np.testing.assert_almost_equal(Lab_to_XYZ(
            np.array([100, 129.04406346, 406.69765889])),
                                       np.array([1.92001986, 1., -0.1241347]),
                                       decimal=7)

        np.testing.assert_almost_equal(Lab_to_XYZ(
            np.array([100, 8.32281957, -73.58297716])),
                                       np.array([1.0131677, 1., 2.11217686]),
                                       decimal=7)

        np.testing.assert_almost_equal(Lab_to_XYZ(
            np.array([100, -13.29228089, -162.12804888]), (0.44757, 0.40745)),
                                       np.array([1.0131677, 1., 2.11217686]),
                                       decimal=7)

        np.testing.assert_almost_equal(Lab_to_XYZ(
            np.array([100, 2.18505384, -56.60990888]), (1 / 3, 1 / 3)),
                                       np.array([1.0131677, 1., 2.11217686]),
                                       decimal=7)

        np.testing.assert_almost_equal(Lab_to_XYZ(
            np.array([100, 10.76832763, -49.42733157]), (0.31271, 0.32902)),
                                       np.array([1.0131677, 1., 2.11217686]),
                                       decimal=7)
예제 #7
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)
예제 #8
0
def is_within_pointer_gamut(XYZ: ArrayLike,
                            tolerance: Optional[Floating] = None) -> NDArray:
    """
    Return whether given *CIE XYZ* tristimulus values are within Pointer's
    Gamut volume.

    Parameters
    ----------
    XYZ
        *CIE XYZ* tristimulus values.
    tolerance
        Tolerance allowed in the inside-triangle check.

    Returns
    -------
    :class:`numpy.ndarray`
        Wether given *CIE XYZ* tristimulus values are within Pointer's Gamut
        volume.

    Notes
    -----
    +------------+-----------------------+---------------+
    | **Domain** | **Scale - Reference** | **Scale - 1** |
    +============+=======================+===============+
    | ``XYZ``    | [0, 1]                | [0, 1]        |
    +------------+-----------------------+---------------+

    Examples
    --------
    >>> import numpy as np
    >>> is_within_pointer_gamut(np.array([0.3205, 0.4131, 0.5100]))
    array(True, dtype=bool)
    >>> a = np.array([[0.3205, 0.4131, 0.5100], [0.0005, 0.0031, 0.0010]])
    >>> is_within_pointer_gamut(a)
    array([ True, False], dtype=bool)
    """

    XYZ_p = Lab_to_XYZ(LCHab_to_Lab(DATA_POINTER_GAMUT_VOLUME),
                       CCS_ILLUMINANT_POINTER_GAMUT)

    return is_within_mesh_volume(XYZ, XYZ_p, tolerance)
예제 #9
0
    def test_Lab_to_XYZ(self):
        """
        Tests :func:`colour.models.cie_lab.Lab_to_XYZ` definition.
        """

        np.testing.assert_almost_equal(
            Lab_to_XYZ(np.array([37.98562910, -23.62907688, -4.41746615])),
            np.array([0.07049534, 0.10080000, 0.09558313]),
            decimal=7)

        np.testing.assert_almost_equal(
            Lab_to_XYZ(np.array([65.70971880, 41.56438554, 37.78303554])),
            np.array([0.47097710, 0.34950000, 0.11301649]),
            decimal=7)

        np.testing.assert_almost_equal(
            Lab_to_XYZ(np.array([50.86223896, 32.76150086, 20.25483590])),
            np.array([0.25506814, 0.19150000, 0.08849752]),
            decimal=7)

        np.testing.assert_almost_equal(
            Lab_to_XYZ(np.array([37.98562910, -32.51333979, -35.96770745]),
                       np.array([0.44757, 0.40745])),
            np.array([0.07049534, 0.10080000, 0.09558313]),
            decimal=7)

        np.testing.assert_almost_equal(
            Lab_to_XYZ(np.array([37.98562910, -22.61920654, 4.19811236]),
                       np.array([0.31270, 0.32900])),
            np.array([0.07049534, 0.10080000, 0.09558313]),
            decimal=7)

        np.testing.assert_almost_equal(
            Lab_to_XYZ(np.array([37.98562910, -25.55521883, -11.26139386]),
                       np.array([0.37208, 0.37529])),
            np.array([0.07049534, 0.10080000, 0.09558313]),
            decimal=7)

        np.testing.assert_almost_equal(
            Lab_to_XYZ(np.array([37.98562910, -25.55521883, -11.26139386]),
                       np.array([0.37208, 0.37529, 0.10080])),
            np.array([0.00710593, 0.01016064, 0.00963478]),
            decimal=7)
예제 #10
0
    def test_Lab_to_XYZ(self):
        """
        Tests :func:`colour.models.cie_lab.Lab_to_XYZ` definition.
        """

        np.testing.assert_almost_equal(
            Lab_to_XYZ(np.array([37.98562910, -23.62302887, -4.41417036])),
            np.array([0.07049534, 0.10080000, 0.09558313]),
            decimal=7)

        np.testing.assert_almost_equal(
            Lab_to_XYZ(np.array([65.70971880, 41.57577646, 37.78652063])),
            np.array([0.47097710, 0.34950000, 0.11301649]),
            decimal=7)

        np.testing.assert_almost_equal(
            Lab_to_XYZ(np.array([50.86223896, 32.77078577, 20.25804815])),
            np.array([0.25506814, 0.19150000, 0.08849752]),
            decimal=7)

        np.testing.assert_almost_equal(
            Lab_to_XYZ(np.array([37.98562910, -32.51333979, -35.96770745]),
                       np.array([0.44757, 0.40745])),
            np.array([0.07049534, 0.10080000, 0.09558313]),
            decimal=7)

        np.testing.assert_almost_equal(
            Lab_to_XYZ(np.array([37.98562910, -22.61718913, 4.19383056]),
                       np.array([0.31271, 0.32902])),
            np.array([0.07049534, 0.10080000, 0.09558313]),
            decimal=7)

        np.testing.assert_almost_equal(
            Lab_to_XYZ(np.array([37.98562910, -25.55521883, -11.26139386]),
                       np.array([0.37208, 0.37529])),
            np.array([0.07049534, 0.10080000, 0.09558313]),
            decimal=7)

        np.testing.assert_almost_equal(
            Lab_to_XYZ(np.array([37.98562910, -25.55521883, -11.26139386]),
                       np.array([0.37208, 0.37529, 0.10080])),
            np.array([0.00710593, 0.01016064, 0.00963478]),
            decimal=7)
예제 #11
0
    def test_Lab_to_XYZ(self):
        """Test :func:`colour.models.cie_lab.Lab_to_XYZ` definition."""

        np.testing.assert_almost_equal(
            Lab_to_XYZ(np.array([41.52787529, 52.63858304, 26.92317922])),
            np.array([0.20654008, 0.12197225, 0.05136952]),
            decimal=7,
        )

        np.testing.assert_almost_equal(
            Lab_to_XYZ(np.array([55.11636304, -41.08791787, 30.91825778])),
            np.array([0.14222010, 0.23042768, 0.10495772]),
            decimal=7,
        )

        np.testing.assert_almost_equal(
            Lab_to_XYZ(np.array([29.80565520, 20.01830466, -48.34913874])),
            np.array([0.07818780, 0.06157201, 0.28099326]),
            decimal=7,
        )

        np.testing.assert_almost_equal(
            Lab_to_XYZ(
                np.array([41.52787529, 38.48089305, -5.73295122]),
                np.array([0.44757, 0.40745]),
            ),
            np.array([0.20654008, 0.12197225, 0.05136952]),
            decimal=7,
        )

        np.testing.assert_almost_equal(
            Lab_to_XYZ(
                np.array([41.52787529, 51.19354174, 19.91843098]),
                np.array([0.34570, 0.35850]),
            ),
            np.array([0.20654008, 0.12197225, 0.05136952]),
            decimal=7,
        )

        np.testing.assert_almost_equal(
            Lab_to_XYZ(
                np.array([41.52787529, 51.19354174, 19.91843098]),
                np.array([0.34570, 0.35850, 1.00000]),
            ),
            np.array([0.20654008, 0.12197225, 0.05136952]),
            decimal=7,
        )
예제 #12
0
Notes
-----
-   *X-Rite* data is given as *CIE L\\*a\\*b\\** colourspace values under
    *CIE Illuminant D Series D50* for the
    *CIE 1931 2 Degree Standard Observer*.

COLORCHECKER24_BEFORE_NOV2014_LAB_DATA : ndarray
"""

COLORCHECKER24_BEFORE_NOV2014_DATA = OrderedDict(
    zip(
        COLORCHECKER24_BEFORE_NOV2014_LAB_DATA.keys(),
        XYZ_to_xyY(
            Lab_to_XYZ(
                list(COLORCHECKER24_BEFORE_NOV2014_LAB_DATA.values()),
                ILLUMINANTS['CIE 1931 2 Degree Standard Observer']['D50']))))

COLORCHECKER24_BEFORE_NOV2014_ILLUMINANT = (
    ILLUMINANTS['CIE 1931 2 Degree Standard Observer']['D50'])
"""
*ColorChecker24 - Before November 2014* illuminant.

COLORCHECKER24_BEFORE_NOV2014_ILLUMINANT : ndarray
"""

COLORCHECKER24_BEFORE_NOV2014 = ColourChecker(
    'ColorChecker24 - Before November 2014',
    COLORCHECKER24_BEFORE_NOV2014_DATA,
    COLORCHECKER24_BEFORE_NOV2014_ILLUMINANT)
"""
예제 #13
0
파일: rgb.py 프로젝트: vidakDK/colour
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)
예제 #14
0
파일: models.py 프로젝트: crowsonkb/colour
def RGB_colourspaces_CIE_1931_chromaticity_diagram_plot(
        colourspaces=None,
        cmfs='CIE 1931 2 Degree Standard Observer',
        **kwargs):
    """
    Plots given *RGB* colourspaces in *CIE 1931 Chromaticity Diagram*.

    Parameters
    ----------
    colourspaces : array_like, optional
        *RGB* colourspaces to plot.
    cmfs : unicode, optional
        Standard observer colour matching functions used for diagram bounds.

    Other Parameters
    ----------------
    \**kwargs : dict, optional
        {:func:`boundaries`, :func:`canvas`, :func:`decorate`,
        :func:`display`},
        Please refer to the documentation of the previously listed definitions.
    show_diagram_colours : bool, optional
        {:func:`CIE_1931_chromaticity_diagram_plot`},
        Whether to display the chromaticity diagram background colours.

    Returns
    -------
    Figure
        Current figure or None.

    Examples
    --------
    >>> c = ['Rec. 709', 'ACEScg', 'S-Gamut']
    >>> RGB_colourspaces_CIE_1931_chromaticity_diagram_plot(
    ...     c)  # doctest: +SKIP
    """

    settings = {'figure_size': (DEFAULT_FIGURE_WIDTH, DEFAULT_FIGURE_WIDTH)}
    settings.update(kwargs)

    canvas(**settings)

    if colourspaces is None:
        colourspaces = ('Rec. 709', 'ACEScg', 'S-Gamut', 'Pointer Gamut')

    cmfs, name = get_cmfs(cmfs), cmfs

    settings = {
        'title':
        '{0} - {1} - CIE 1931 Chromaticity Diagram'.format(
            ', '.join(colourspaces), name),
        'standalone':
        False
    }
    settings.update(kwargs)

    CIE_1931_chromaticity_diagram_plot(**settings)

    x_limit_min, x_limit_max = [-0.1], [0.9]
    y_limit_min, y_limit_max = [-0.1], [0.9]

    settings = {
        'colour_cycle_map': 'rainbow',
        'colour_cycle_count': len(colourspaces)
    }
    settings.update(kwargs)

    cycle = colour_cycle(**settings)

    for colourspace in colourspaces:
        if colourspace == 'Pointer Gamut':
            xy = np.asarray(POINTER_GAMUT_BOUNDARIES)
            alpha_p, colour_p = 0.85, '0.95'
            pylab.plot(xy[..., 0],
                       xy[..., 1],
                       label='Pointer\'s Gamut',
                       color=colour_p,
                       alpha=alpha_p,
                       linewidth=2)
            pylab.plot((xy[-1][0], xy[0][0]), (xy[-1][1], xy[0][1]),
                       color=colour_p,
                       alpha=alpha_p,
                       linewidth=2)

            XYZ = Lab_to_XYZ(LCHab_to_Lab(POINTER_GAMUT_DATA),
                             POINTER_GAMUT_ILLUMINANT)
            xy = XYZ_to_xy(XYZ, POINTER_GAMUT_ILLUMINANT)
            pylab.scatter(xy[..., 0],
                          xy[..., 1],
                          alpha=alpha_p / 2,
                          color=colour_p,
                          marker='+')

        else:
            colourspace, name = get_RGB_colourspace(colourspace), colourspace

            r, g, b, _a = next(cycle)

            primaries = colourspace.primaries
            whitepoint = colourspace.whitepoint

            pylab.plot((whitepoint[0], whitepoint[0]),
                       (whitepoint[1], whitepoint[1]),
                       color=(r, g, b),
                       label=colourspace.name,
                       linewidth=2)
            pylab.plot((whitepoint[0], whitepoint[0]),
                       (whitepoint[1], whitepoint[1]),
                       'o',
                       color=(r, g, b),
                       linewidth=2)
            pylab.plot((primaries[0, 0], primaries[1, 0]),
                       (primaries[0, 1], primaries[1, 1]),
                       'o-',
                       color=(r, g, b),
                       linewidth=2)
            pylab.plot((primaries[1, 0], primaries[2, 0]),
                       (primaries[1, 1], primaries[2, 1]),
                       'o-',
                       color=(r, g, b),
                       linewidth=2)
            pylab.plot((primaries[2, 0], primaries[0, 0]),
                       (primaries[2, 1], primaries[0, 1]),
                       'o-',
                       color=(r, g, b),
                       linewidth=2)

            x_limit_min.append(np.amin(primaries[..., 0]) - 0.1)
            y_limit_min.append(np.amin(primaries[..., 1]) - 0.1)
            x_limit_max.append(np.amax(primaries[..., 0]) + 0.1)
            y_limit_max.append(np.amax(primaries[..., 1]) + 0.1)

    settings.update({
        'legend':
        True,
        'legend_location':
        'upper right',
        'x_tighten':
        True,
        'y_tighten':
        True,
        'limits': (min(x_limit_min), max(x_limit_max), min(y_limit_min),
                   max(y_limit_max)),
        'standalone':
        True
    })
    settings.update(kwargs)

    boundaries(**settings)
    decorate(**settings)

    return display(**settings)
예제 #15
0
def RGB_colourspaces_CIE_1976_UCS_chromaticity_diagram_plot(
        colourspaces=None,
        cmfs='CIE 1931 2 Degree Standard Observer',
        **kwargs):
    """
    Plots given *RGB* colourspaces in *CIE 1976 UCS Chromaticity Diagram*.

    Parameters
    ----------
    colourspaces : array_like, optional
        *RGB* colourspaces to plot.
    cmfs : unicode, optional
        Standard observer colour matching functions used for diagram bounds.

    Other Parameters
    ----------------
    \**kwargs : dict, optional
        {:func:`boundaries`, :func:`canvas`, :func:`decorate`,
        :func:`display`},
        Please refer to the documentation of the previously listed definitions.
    show_diagram_colours : bool, optional
        {:func:`CIE_1976_UCS_chromaticity_diagram_plot`},
        Whether to display the chromaticity diagram background colours.

    Returns
    -------
    Figure
        Current figure or None.

    Examples
    --------
    >>> c = ['Rec. 709', 'ACEScg', 'S-Gamut']
    >>> RGB_colourspaces_CIE_1976_UCS_chromaticity_diagram_plot(
    ...     c)  # doctest: +SKIP
    """

    settings = {'figure_size': (DEFAULT_FIGURE_WIDTH, DEFAULT_FIGURE_WIDTH)}
    settings.update(kwargs)

    canvas(**settings)

    if colourspaces is None:
        colourspaces = ('Rec. 709', 'ACEScg', 'S-Gamut', 'Pointer Gamut')

    cmfs, name = get_cmfs(cmfs), cmfs

    illuminant = DEFAULT_PLOTTING_ILLUMINANT

    settings = {
        'title':
        '{0} - {1} - CIE 1976 UCS Chromaticity Diagram'.format(
            ', '.join(colourspaces), name),
        'standalone':
        False
    }
    settings.update(kwargs)

    CIE_1976_UCS_chromaticity_diagram_plot(**settings)

    x_limit_min, x_limit_max = [-0.1], [0.7]
    y_limit_min, y_limit_max = [-0.1], [0.7]

    settings = {
        'colour_cycle_map': 'rainbow',
        'colour_cycle_count': len(colourspaces)
    }
    settings.update(kwargs)

    cycle = colour_cycle(**settings)

    for colourspace in colourspaces:
        if colourspace == 'Pointer Gamut':
            uv = Luv_to_uv(
                XYZ_to_Luv(xy_to_XYZ(POINTER_GAMUT_BOUNDARIES), illuminant),
                illuminant)
            alpha_p, colour_p = 0.85, '0.95'
            pylab.plot(uv[..., 0],
                       uv[..., 1],
                       label='Pointer\'s Gamut',
                       color=colour_p,
                       alpha=alpha_p,
                       linewidth=2)
            pylab.plot((uv[-1][0], uv[0][0]), (uv[-1][1], uv[0][1]),
                       color=colour_p,
                       alpha=alpha_p,
                       linewidth=2)

            XYZ = Lab_to_XYZ(LCHab_to_Lab(POINTER_GAMUT_DATA),
                             POINTER_GAMUT_ILLUMINANT)
            uv = Luv_to_uv(XYZ_to_Luv(XYZ, illuminant), illuminant)
            pylab.scatter(uv[..., 0],
                          uv[..., 1],
                          alpha=alpha_p / 2,
                          color=colour_p,
                          marker='+')

        else:
            colourspace, name = get_RGB_colourspace(colourspace), colourspace

            r, g, b, _a = next(cycle)

            # RGB colourspaces such as *ACES2065-1* have primaries with
            # chromaticity coordinates set to 0 thus we prevent nan from being
            # yield by zero division in later colour transformations.
            P = np.where(colourspace.primaries == 0, EPSILON,
                         colourspace.primaries)

            P = Luv_to_uv(XYZ_to_Luv(xy_to_XYZ(P), illuminant), illuminant)
            W = Luv_to_uv(
                XYZ_to_Luv(xy_to_XYZ(colourspace.whitepoint), illuminant),
                illuminant)

            pylab.plot((W[0], W[0]), (W[1], W[1]),
                       color=(r, g, b),
                       label=colourspace.name,
                       linewidth=2)
            pylab.plot((W[0], W[0]), (W[1], W[1]),
                       'o',
                       color=(r, g, b),
                       linewidth=2)
            pylab.plot((P[0, 0], P[1, 0]), (P[0, 1], P[1, 1]),
                       'o-',
                       color=(r, g, b),
                       linewidth=2)
            pylab.plot((P[1, 0], P[2, 0]), (P[1, 1], P[2, 1]),
                       'o-',
                       color=(r, g, b),
                       linewidth=2)
            pylab.plot((P[2, 0], P[0, 0]), (P[2, 1], P[0, 1]),
                       'o-',
                       color=(r, g, b),
                       linewidth=2)

            x_limit_min.append(np.amin(P[..., 0]) - 0.1)
            y_limit_min.append(np.amin(P[..., 1]) - 0.1)
            x_limit_max.append(np.amax(P[..., 0]) + 0.1)
            y_limit_max.append(np.amax(P[..., 1]) + 0.1)

    settings.update({
        'legend':
        True,
        'legend_location':
        'upper right',
        'x_tighten':
        True,
        'y_tighten':
        True,
        'limits': (min(x_limit_min), max(x_limit_max), min(y_limit_min),
                   max(y_limit_max)),
        'standalone':
        True
    })
    settings.update(kwargs)

    boundaries(**settings)
    decorate(**settings)

    return display(**settings)
예제 #16
0
def DIN99_to_XYZ(
    Lab_99: ArrayLike,
    illuminant: ArrayLike = CCS_ILLUMINANTS[
        "CIE 1931 2 Degree Standard Observer"]["D65"],
    k_E: Floating = 1,
    k_CH: Floating = 1,
    method: Union[Literal["ASTMD2244-07", "DIN99", "DIN99b", "DIN99c",
                          "DIN99d"], str] = "DIN99",
) -> NDArray:
    """
    Convert from *DIN99* colourspace or one of the *DIN99b*, *DIN99c*,
    *DIN99d* refined formulas according to *Cui et al. (2002)* to *CIE XYZ*
    tristimulus values.

    Parameters
    ----------
    Lab_99
        *DIN99* colourspace array.
    illuminant
        Reference *illuminant* *CIE xy* chromaticity coordinates or *CIE xyY*
        colourspace array.
    k_E
        Parametric factor :math:`K_E` used to compensate for texture and other
        specimen presentation effects.
    k_CH
        Parametric factor :math:`K_{CH}` used to compensate for texture and
        other specimen presentation effects.
    method
        Computation method to choose between the :cite:`ASTMInternational2007`
        formula and the refined formulas according to *Cui et al. (2002)*.

    Returns
    -------
    :class:`numpy.ndarray`
        *CIE XYZ* tristimulus values.

    Notes
    -----
    +----------------+------------------------+--------------------+
    | **Domain**     | **Scale - Reference**  | **Scale - 1**      |
    +================+========================+====================+
    | ``Lab_99``     | ``L_99`` : [0, 100]    | ``L_99`` : [0, 1]  |
    |                |                        |                    |
    |                | ``a_99`` : [-100, 100] | ``a_99`` : [-1, 1] |
    |                |                        |                    |
    |                | ``b_99`` : [-100, 100] | ``b_99`` : [-1, 1] |
    +----------------+------------------------+--------------------+
    | ``illuminant`` | [0, 1]                 | [0, 1]             |
    +----------------+------------------------+--------------------+

    +----------------+-----------------------+---------------------+
    | **Range**      | **Scale - Reference** | **Scale - 1**       |
    +================+=======================+=====================+
    | ``XYZ``        | [0, 1]                | [0, 1]              |
    +----------------+-----------------------+---------------------+

    References
    ----------
    :cite:`ASTMInternational2007`

    Examples
    --------
    >>> import numpy as np
    >>> Lab_99 = np.array([53.22821989, 28.41634656, 3.89839552])
    >>> DIN99_to_XYZ(Lab_99)  # doctest: +ELLIPSIS
    array([ 0.2065400...,  0.1219722...,  0.0513695...])
    """

    Lab = DIN99_to_Lab(Lab_99, k_E, k_CH, method)

    return Lab_to_XYZ(Lab, illuminant)
예제 #17
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)
예제 #18
0
def RGB_colourspaces_CIE_1960_UCS_chromaticity_diagram_plot(
        colourspaces=None,
        cmfs='CIE 1931 2 Degree Standard Observer',
        **kwargs):
    """
    Plots given *RGB* colourspaces in *CIE 1960 UCS Chromaticity Diagram*.

    Parameters
    ----------
    colourspaces : array_like, optional
        *RGB* colourspaces to plot.
    cmfs : unicode, optional
        Standard observer colour matching functions used for diagram bounds.
    \**kwargs : dict, optional
        Keywords arguments.

    Returns
    -------
    bool
        Definition success.

    Examples
    --------
    >>> c = ['Rec. 709', 'ACEScg', 'S-Gamut']
    >>> RGB_colourspaces_CIE_1960_UCS_chromaticity_diagram_plot(
    ...     c)  # doctest: +SKIP
    True
    """

    settings = {'figure_size': (DEFAULT_FIGURE_WIDTH, DEFAULT_FIGURE_WIDTH)}
    settings.update(kwargs)

    canvas(**settings)

    if colourspaces is None:
        colourspaces = ('Rec. 709', 'ACEScg', 'S-Gamut', 'Pointer Gamut')

    cmfs, name = get_cmfs(cmfs), cmfs

    settings = {
        'title': '{0} - {1} - CIE 1960 UCS Chromaticity Diagram'.format(
            ', '.join(colourspaces), name),
        'standalone': False}
    settings.update(kwargs)

    CIE_1960_UCS_chromaticity_diagram_plot(**settings)

    x_limit_min, x_limit_max = [-0.1], [0.7]
    y_limit_min, y_limit_max = [-0.2], [0.6]

    settings = {'colour_cycle_map': 'rainbow',
                'colour_cycle_count': len(colourspaces)}
    settings.update(kwargs)

    cycle = colour_cycle(**settings)

    for colourspace in colourspaces:
        if colourspace == 'Pointer Gamut':
            uv = UCS_to_uv(XYZ_to_UCS(xy_to_XYZ(POINTER_GAMUT_BOUNDARIES)))
            alpha_p, colour_p = 0.85, '0.95'
            pylab.plot(uv[..., 0],
                       uv[..., 1],
                       label='Pointer\'s Gamut',
                       color=colour_p,
                       alpha=alpha_p,
                       linewidth=2)
            pylab.plot((uv[-1][0], uv[0][0]),
                       (uv[-1][1], uv[0][1]),
                       color=colour_p,
                       alpha=alpha_p,
                       linewidth=2)

            XYZ = Lab_to_XYZ(LCHab_to_Lab(POINTER_GAMUT_DATA),
                             POINTER_GAMUT_ILLUMINANT)
            uv = UCS_to_uv(XYZ_to_UCS(XYZ))
            pylab.scatter(uv[..., 0],
                          uv[..., 1],
                          alpha=alpha_p / 2,
                          color=colour_p,
                          marker='+')

        else:
            colourspace, name = get_RGB_colourspace(colourspace), colourspace

            r, g, b, _a = next(cycle)

            # RGB colourspaces such as *ACES2065-1* have primaries with
            # chromaticity coordinates set to 0 thus we prevent nan from being
            # yield by zero division in later colour transformations.
            primaries = np.where(colourspace.primaries == 0,
                                 EPSILON,
                                 colourspace.primaries)

            primaries = UCS_to_uv(XYZ_to_UCS(xy_to_XYZ(primaries)))
            whitepoint = UCS_to_uv(XYZ_to_UCS(xy_to_XYZ(
                colourspace.whitepoint)))

            pylab.plot((whitepoint[0], whitepoint[0]),
                       (whitepoint[1], whitepoint[1]),
                       color=(r, g, b),
                       label=colourspace.name,
                       linewidth=2)
            pylab.plot((whitepoint[0], whitepoint[0]),
                       (whitepoint[1], whitepoint[1]),
                       'o',
                       color=(r, g, b),
                       linewidth=2)
            pylab.plot((primaries[0, 0], primaries[1, 0]),
                       (primaries[0, 1], primaries[1, 1]),
                       'o-',
                       color=(r, g, b),
                       linewidth=2)
            pylab.plot((primaries[1, 0], primaries[2, 0]),
                       (primaries[1, 1], primaries[2, 1]),
                       'o-',
                       color=(r, g, b),
                       linewidth=2)
            pylab.plot((primaries[2, 0], primaries[0, 0]),
                       (primaries[2, 1], primaries[0, 1]),
                       'o-',
                       color=(r, g, b),
                       linewidth=2)

            x_limit_min.append(np.amin(primaries[..., 0]) - 0.1)
            y_limit_min.append(np.amin(primaries[..., 1]) - 0.1)
            x_limit_max.append(np.amax(primaries[..., 0]) + 0.1)
            y_limit_max.append(np.amax(primaries[..., 1]) + 0.1)

    settings.update({
        'legend': True,
        'legend_location': 'upper right',
        'x_tighten': True,
        'y_tighten': True,
        'limits': (min(x_limit_min), max(x_limit_max),
                   min(y_limit_min), max(y_limit_max)),
        'standalone': True})
    settings.update(kwargs)

    boundaries(**settings)
    decorate(**settings)

    return display(**settings)
예제 #19
0
Notes
-----
-   *X-Rite* data is given as *CIE L\\*a\\*b\\** colourspace values under
    *CIE Illuminant D Series D50* for the
    *CIE 1931 2 Degree Standard Observer*.

DATA_COLORCHECKER24_BEFORE_NOV2014 : ndarray
"""

DATA_COLORCHECKER24_BEFORE_NOV2014 = OrderedDict(
    zip(
        SAMPLE_LABELS_COLORCHECKER_CLASSIC,
        XYZ_to_xyY(
            Lab_to_XYZ(
                list(DATA_COLORCHECKER24_BEFORE_NOV2014.values()),
                CCS_ILLUMINANTS['CIE 1931 2 Degree Standard Observer']
                ['ICC D50']))))

CCS_ILLUMINANT_COLORCHECKER24_BEFORE_NOV2014 = (
    CCS_ILLUMINANTS['CIE 1931 2 Degree Standard Observer']['ICC D50'])
"""
*ColorChecker24 - Before November 2014* illuminant.

CCS_ILLUMINANT_COLORCHECKER24_BEFORE_NOV2014 : ndarray
"""

CCS_COLORCHECKER24_BEFORE_NOV2014 = ColourChecker(
    'ColorChecker24 - Before November 2014',
    DATA_COLORCHECKER24_BEFORE_NOV2014,
    CCS_ILLUMINANT_COLORCHECKER24_BEFORE_NOV2014)
"""
예제 #20
0
파일: models.py 프로젝트: ajun73/Work_Code
def plot_pointer_gamut(method='CIE 1931', **kwargs):
    """
    Plots *Pointer's Gamut* according to given method.

    Parameters
    ----------
    method : unicode, optional
        **{'CIE 1931', 'CIE 1960 UCS', 'CIE 1976 UCS'}**,
        Plotting method.

    Other Parameters
    ----------------
    \\**kwargs : dict, optional
        {:func:`colour.plotting.artist`, :func:`colour.plotting.render`},
        Please refer to the documentation of the previously listed definitions.

    Returns
    -------
    tuple
        Current figure and axes.

    Examples
    --------
    >>> plot_pointer_gamut()  # doctest: +SKIP

    .. image:: ../_static/Plotting_Plot_Pointer_Gamut.png
        :align: center
        :alt: plot_pointer_gamut
    """

    settings = {'uniform': True}
    settings.update(kwargs)

    figure, axes = artist(**settings)

    method = method.upper()

    if method == 'CIE 1931':

        def XYZ_to_ij(XYZ, *args):
            """
            Converts given *CIE XYZ* tristimulus values to *ij* chromaticity
            coordinates.
            """

            return XYZ_to_xy(XYZ, *args)

        def xy_to_ij(xy):
            """
            Converts given *xy* chromaticity coordinates to *ij* chromaticity
            coordinates.
            """

            return xy

    elif method == 'CIE 1960 UCS':

        def XYZ_to_ij(XYZ, *args):
            """
            Converts given *CIE XYZ* tristimulus values to *ij* chromaticity
            coordinates.
            """

            return UCS_to_uv(XYZ_to_UCS(XYZ))

        def xy_to_ij(xy):
            """
            Converts given *xy* chromaticity coordinates to *ij* chromaticity
            coordinates.
            """

            return xy_to_UCS_uv(xy)

    elif method == 'CIE 1976 UCS':

        def XYZ_to_ij(XYZ, *args):
            """
            Converts given *CIE XYZ* tristimulus values to *ij* chromaticity
            coordinates.
            """

            return Luv_to_uv(XYZ_to_Luv(XYZ, *args), *args)

        def xy_to_ij(xy):
            """
            Converts given *xy* chromaticity coordinates to *ij* chromaticity
            coordinates.
            """

            return xy_to_Luv_uv(xy)

    else:
        raise ValueError(
            'Invalid method: "{0}", must be one of '
            '{\'CIE 1931\', \'CIE 1960 UCS\', \'CIE 1976 UCS\'}'.format(
                method))

    ij = xy_to_ij(as_float_array(POINTER_GAMUT_BOUNDARIES))
    alpha_p = COLOUR_STYLE_CONSTANTS.opacity.high
    colour_p = COLOUR_STYLE_CONSTANTS.colour.darkest
    axes.plot(ij[..., 0],
              ij[..., 1],
              label='Pointer\'s Gamut',
              color=colour_p,
              alpha=alpha_p)
    axes.plot((ij[-1][0], ij[0][0]), (ij[-1][1], ij[0][1]),
              color=colour_p,
              alpha=alpha_p)

    XYZ = Lab_to_XYZ(LCHab_to_Lab(POINTER_GAMUT_DATA),
                     POINTER_GAMUT_ILLUMINANT)
    ij = XYZ_to_ij(XYZ, POINTER_GAMUT_ILLUMINANT)
    axes.scatter(ij[..., 0],
                 ij[..., 1],
                 alpha=alpha_p / 2,
                 color=colour_p,
                 marker='+')

    settings.update({'axes': axes})
    settings.update(kwargs)

    return render(**settings)
            np.array([96.539, -0.425, 1.186]),
            np.array([81.257, -0.638, -0.335]),
            np.array([66.766, -0.734, -0.504]),
            np.array([50.867, -0.153, -0.27]),
            np.array([35.656, -0.421, -1.231]),
            np.array([20.461, -0.079, -0.973]),
        ],
    ))

DATA_COLORCHECKER24_BEFORE_NOV2014: Dict = dict(
    zip(
        SAMPLE_LABELS_COLORCHECKER_CLASSIC,
        XYZ_to_xyY(
            Lab_to_XYZ(
                list(DATA_COLORCHECKER24_BEFORE_NOV2014_CIE_LAB.values()),
                CCS_ILLUMINANTS["CIE 1931 2 Degree Standard Observer"]
                ["ICC D50"],
            )),
    ))

CCS_ILLUMINANT_COLORCHECKER24_BEFORE_NOV2014: NDArray = CCS_ILLUMINANTS[
    "CIE 1931 2 Degree Standard Observer"]["ICC D50"]
"""*ColorChecker24 - Before November 2014* illuminant."""

CCS_COLORCHECKER24_BEFORE_NOV2014: ColourChecker = ColourChecker(
    "ColorChecker24 - Before November 2014",
    DATA_COLORCHECKER24_BEFORE_NOV2014,
    CCS_ILLUMINANT_COLORCHECKER24_BEFORE_NOV2014,
)
"""
Reference *ColorChecker Classic* data from *X-Rite (2015)*.