예제 #1
0
def XYZ_to_sd_Otsu2018(
        XYZ,
        cmfs=STANDARD_OBSERVER_CMFS['CIE 1931 2 Degree Standard Observer'].
    copy().align(OTSU_2018_SPECTRAL_SHAPE),
        illuminant=ILLUMINANT_SDS['D65'].copy().align(
            OTSU_2018_SPECTRAL_SHAPE),
        clip=True):
    XYZ = as_float_array(XYZ)
    xy = XYZ_to_xy(XYZ)
    cluster = select_cluster_Otsu2018(xy)

    basis_functions = OTSU_2018_BASIS_FUNCTIONS[cluster]
    mean = OTSU_2018_MEANS[cluster]

    M = np.empty((3, 3))
    for i in range(3):
        sd = SpectralDistribution(
            basis_functions[i, :],
            OTSU_2018_SPECTRAL_SHAPE.range(),
        )
        M[:, i] = sd_to_XYZ(sd, illuminant=illuminant) / 100
    M_inverse = np.linalg.inv(M)

    sd = SpectralDistribution(mean, OTSU_2018_SPECTRAL_SHAPE.range())
    XYZ_mu = sd_to_XYZ(sd, illuminant=illuminant) / 100

    weights = np.dot(M_inverse, XYZ - XYZ_mu)
    recovered_sd = np.dot(weights, basis_functions) + mean

    if clip:
        recovered_sd = np.clip(recovered_sd, 0, 1)

    return SpectralDistribution(recovered_sd, OTSU_2018_SPECTRAL_SHAPE.range())
예제 #2
0
def luminance_sd(spectrum, colourspace=RGB_COLOURSPACES['sRGB']):
    """
    Returns the luminance spectral distribution of given RGB spectrum.

    Parameters
    ----------
    spectrum : RGB_Spectrum
        RGB spectrum to retrieve the luminance from.
    colourspace : RGB_Colourspace
        *RGB* Colourspace.

    Returns
    -------
    SpectralDistribution
        RGB spectrum luminance spectral distribution, units are arbitrary
        and normalised to [0, 100] domain.
    """

    spectrum = spectrum.copy().normalise(100)
    luminance = lambda x: RGB_luminance(x, colourspace.primaries, colourspace.
                                        whitepoint)

    return SpectralDistribution(
        dict(zip(spectrum.wavelengths, luminance(spectrum.values))),
        name='calibrated_RGB_spectrum')
예제 #3
0
    def load(self):
        """
        Syncs, parses, converts and returns the *Labsphere (2019)*
        *Labsphere SRS-99-020* dataset content.

        Returns
        -------
        OrderedDict
            *Labsphere (2019)* *Labsphere SRS-99-020* dataset content.

        Examples
        --------
        >>> from colour_datasets.utilities import suppress_stdout
        >>> dataset = DatasetLoader_Labsphere2019()
        >>> with suppress_stdout():
        ...     dataset.load()
        >>> len(dataset.content.keys())
        1
        """

        super(DatasetLoader_Labsphere2019, self).sync()

        sd_path = os.path.join(self.record.repository, 'dataset',
                               'SRS-99-020.txt')

        values = tsplit(np.loadtxt(sd_path, delimiter='\t', skiprows=2))
        self._content = OrderedDict([
            ('Labsphere SRS-99-020',
             SpectralDistribution(values[1],
                                  values[0],
                                  name='Labsphere SRS-99-020')),
        ])

        return self._content
예제 #4
0
    def _reconstruct_xy(self, XYZ, xy):
        if not self.leaf:
            if xy[self.partition_axis.direction] <= self.partition_axis.origin:
                return self.children[0]._reconstruct_xy(XYZ, xy)
            else:
                return self.children[1]._reconstruct_xy(XYZ, xy)

        weights = np.dot(self.M_inverse, XYZ - self.XYZ_mu)
        reflectance = np.dot(weights, self.basis_functions) + self.mean
        reflectance = np.clip(reflectance, 0, 1)
        return SpectralDistribution(reflectance, self.tree.wl)
예제 #5
0
파일: color.py 프로젝트: DuraMAT/pvarc
def spectrum_to_XYZ(
    wavelength,
    spectrum,
    # cmfs=None,
    illuminant=None,
):
    """
    Calculate the rgb color given a wavelength and spectrum

    Parameters
    ----------
    wavelength
    spectrum
    cmfs
    illuminant

    Returns
    -------

    """
    # if cmfs is None:
    # cmfs = colour.STANDARD_OBSERVERS_CMFS['CIE 1931 2 Degree Standard Observer']

    if illuminant is None:
        # illuminant = ILLUMINANTS_SDS['CIE 1931 2 Degree Standard Observer']['D65']
        illuminant = sd_ones()
    elif type(illuminant) == type(''):
        illuminant = SDS_ILLUMINANTS[illuminant]
    # # Get illuminant
    # if type(illuminant) == type(''):
    #     illuminant = colour.ILLUMINANTS_SDS[illuminant]

    # Build spectral distribution object
    sd = SpectralDistribution(pd.Series(spectrum, index=wavelength),
                              interpolator=CubicSplineInterpolator,
                              extrapolator=Extrapolator)

    # Calculate xyz color coordinates.
    xyz = sd_to_XYZ(sd=sd, illuminant=illuminant)

    return xyz
예제 #6
0
    def load(self):
        """
        Syncs, parses, converts and returns the *Brendel (2020)*
        *Measured Commercial LED Spectra* dataset content.

        Returns
        -------
        OrderedDict
            *Brendel (2020)* *Measured Commercial LED Spectra* dataset content.

        Examples
        --------
        >>> from colour_datasets.utilities import suppress_stdout
        >>> dataset = DatasetLoader_Brendel2020()
        >>> with suppress_stdout():
        ...     dataset.load()
        >>> len(dataset.content.keys())
        29
        """

        super(DatasetLoader_Brendel2020, self).sync()

        self._content = OrderedDict()

        wavelengths = SpectralShape(350, 700, 2).range()

        csv_path = os.path.join(self.record.repository, 'dataset',
                                'led_spd_350_700.csv')

        for i, values in enumerate(
                np.loadtxt(csv_path, delimiter=',', skiprows=1)):
            peak = as_int(wavelengths[np.argmax(values)])
            name = '{0}nm - LED {1} - Brendel (2020)'.format(peak, i)

            self._content[name] = SpectralDistribution(
                values,
                wavelengths,
                name=name,
                interpolator=LinearInterpolator)

        return self._content
예제 #7
0
def read_sds_from_mat_file_KuopioUniversity(mat_file, metadata):
    """
    Reads the spectral distributions from given *University of Kuopio*
    *Matlab* *.mat* file.

    Parameters
    ----------
    mat_file : unicode
        *Matlab* *.mat* file.
    metadata : MatFileMetadata_KuopioUniversity
        Metadata required to read the spectral distributions in the *Matlab*
        *.mat* file.

    Returns
    -------
    OrderedDict
        Spectral distributions from the *Matlab* *.mat* file.
    """

    matlab_data = scipy.io.loadmat(mat_file)

    sds = OrderedDict()
    table = matlab_data[metadata.key]
    wavelengths = metadata.shape.range()

    if metadata.transpose:
        table = np.transpose(table)

    for i, data in enumerate(table):
        identifier = six.text_type(i + 1 if metadata.identifiers is None else
                                   matlab_data[metadata.identifiers][
                                       i].strip())

        if identifier in sds:
            identifier = '{0} ({1})'.format(identifier, i)

        sds[identifier] = SpectralDistribution(
            dict(zip(wavelengths, data)), name=identifier)

    return sds
예제 #8
0
    def __init__(self, tree, reflectances):
        """
        Parameters
        ==========
        tree : tree
            The parent tree. This determines what cmfs and illuminant
            are used in colourimetric calculations.
        reflectances : ndarray (n,m)
            Reflectances of the ``n`` colours to be stored in this class.
            The shape must match ``tree.shape`` with ``m`` points for
            each colour.
        """

        self.reflectances = reflectances
        self.XYZ = np.empty((reflectances.shape[0], 3))
        self.xy = np.empty((reflectances.shape[0], 2))

        for i in range(len(self)):
            sd = SpectralDistribution(reflectances[i, :], tree.wl)
            XYZ = sd_to_XYZ(sd, illuminant=tree.illuminant) / 100
            self.XYZ[i, :] = XYZ
            self.xy[i, :] = XYZ_to_xy(XYZ)
예제 #9
0
    weights = np.dot(M_inverse, XYZ - XYZ_mu)
    recovered_sd = np.dot(weights, basis_functions) + mean

    if clip:
        recovered_sd = np.clip(recovered_sd, 0, 1)

    return SpectralDistribution(recovered_sd, OTSU_2018_SPECTRAL_SHAPE.range())


if __name__ == '__main__':
    print('Loading spectral data...')
    data = load_Otsu2018_spectra('CommonData/spectrum_m.csv')
    shape = SpectralShape(380, 730, 10)
    sds = [
        SpectralDistribution(data[i, :], shape.range())
        for i in range(data.shape[0])
    ]

    for name, colourchecker in COLOURCHECKER_SDS.items():
        print('Adding %s...' % name)
        sds += colourchecker.values()

    D65 = ILLUMINANT_SDS['D65']
    xy_w = ILLUMINANTS['CIE 1931 2 Degree Standard Observer']['D65']

    x = []
    y = []
    errors = []
    above_JND = 0
    for i, sd in tqdm.tqdm(enumerate(sds), total=len(sds)):