Определите, что цвет Luv не мнимый - PullRequest
0 голосов
/ 15 мая 2018

Предположим, у меня есть тройка координат в цветовом пространстве Luv.Как лучше всего определить, соответствуют ли они реальному цвету?

Ответы [ 2 ]

0 голосов
/ 17 мая 2018

У вас есть Lu'v' координаты. Вы можете проверить L и ограничить допустимое значение. Часто мы не допускаем, чтобы L был больше, чем L белого, но реальность (и старый телевизионный стандарт) позволяла это, только для небольшого периода или маленькой поверхности (иначе он станет новым белым из-за адаптации глаза).

Первый шаг: преобразовать его в XYZ (или любые трехстимульные координаты) В Википедии есть одна из формул в https://en.wikipedia.org/wiki/CIELUV#The_reverse_transformation, но имейте в виду, что она предназначена для одного конкретного диапазона u и v и конкретной гамма коррекции.

Затем вы конвертируете его в цветовое пространство LMS, например, https://en.wikipedia.org/wiki/LMS_color_space

Наконец: убедитесь, что L, M и S положительны (L, M, S цветового пространства LMS: примечание L - это не то же самое L LUV, в этом случае это расшифровывается как L ong cone type).

Если координаты LMS положительные, цвет является реальным и видимым. В другом случае невозможно произвести такой свет.

LSM обозначает отклик глазного конуса типов конусов L, M и S, поэтому он является окончательным ответом на видимость цветов. Проблема в том, что сложно измерить реакцию на один глазной конус. По этой причине вы видите различные матрицы преобразования между XYZ и LMS. С другой стороны, результаты похожи. Примечание: из-за сложности прямых измерений матрицы были получены также косвенно (с использованием метода, аналогичного келевскому ответу, но не только для поверхности).

0 голосов
/ 16 мая 2018

Предполагая, что ваш L * находится в домене [0, 100], вы можете построить границы видимого спектра и затем определить, находятся ли в нем ваши координаты CIE L * u * v *.

import colour
import numpy as np


def generate_square_waves(samples):
    square_waves = []
    square_waves_basis = np.tril(np.ones((samples, samples)))[0:-1, :]
    for i in range(samples):
        square_waves.append(np.roll(square_waves_basis, i))
    return np.vstack((np.zeros(samples), np.vstack(square_waves),
                    np.ones(samples)))


def XYZ_outer_surface(samples):
    XYZ = []
    wavelengths = np.linspace(colour.DEFAULT_SPECTRAL_SHAPE.start,
                            colour.DEFAULT_SPECTRAL_SHAPE.end, samples)

    for wave in generate_square_waves(samples):
        spd = colour.SpectralPowerDistribution(
            wave, wavelengths, interpolator=colour.LinearInterpolator).align(
                colour.DEFAULT_SPECTRAL_SHAPE)
        XYZ.append(colour.spectral_to_XYZ(spd))

    return np.array(XYZ).reshape(len(XYZ), -1, 3)

mesh = XYZ_outer_surface(43).reshape((-1, 3))

E = colour.ILLUMINANTS['CIE 1931 2 Degree Standard Observer']['E']

XYZ1 = colour.Luv_to_XYZ([50, 50, 50], E)
print(colour.is_within_mesh_volume(XYZ1, mesh))
# True

XYZ2 = colour.Luv_to_XYZ([50, 250, -250], E)
print(colour.is_within_mesh_volume(XYZ2, mesh))
# False

Я бы настоятельно рекомендовал кэшировать меш, так как он довольно тяжел для вычислений.

...