Перейти к содержимому
Форум химиков на XuMuK.ru
  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу

kciray

Как из спектра видимого диапазона получить RGB значения?

Рекомендуемые сообщения

Я хочу написать функцию на С++, которая, получая пучёк света видимого диапазона (например массив , каждый элемент которого от 400 до 790 принимает значение true\false - есть ли волны этого диапазона в пучке), возвращает GRB значение.

Читал статью про метомерию. Есть 3 графика для R G и B. Вот только я не понял, как из них получить сами значения цвета?Суммировать? У кого какие мысли есть?

Поделиться сообщением


Ссылка на сообщение

Когда я переводил RGB излучения моих люминофоров в нанометры и наоборот я пользовался программкой Spectra

 

Я это все понимаю, что человеческий глаз инициирует каждую электромагнитную волну по-разному, и быть тут простой формулы или уравнения не может по определению :(

Поделиться сообщением


Ссылка на сообщение

Я хочу написать функцию на С++, которая, получая пучёк света видимого диапазона (например массив , каждый элемент которого от 400 до 790 принимает значение true\false - есть ли волны этого диапазона в пучке), возвращает GRB значение.

Читал статью про метомерию. Есть 3 графика для R G и B. Вот только я не понял, как из них получить сами значения цвета?Суммировать? У кого какие мысли есть?

Не понятно, что вы хотите получить на выходе.

Ну и получайте себе цвета в RGB. Куда вы собрались преобразоваыать RGB, а главное зачем? Что значит "значения цвета"?

Если есть значение цвета в кодировке RGB, можно его вывести на экран с помощью программы, которая ее воспринимает. Преобразовние уже давно написано и "зашито" в микропроцессор монитора/драйвер принтера.

 

true\false - есть ли волны этого диапазона в пучке)

Ничего не получится при таком раскладе.

Нужно брать массив с интенисивностью цвета данной длинны волны. Иначе какой иненсивности брать волны?

 

Пусть есть спектр излучения I(λ) (ваш массив - зависимость интенсивности от длинны волны).

То, что воспринимает человечесчкий глаз (собтсвенно цвет объекта) представляет собой интеграл :

 

Int( I(λ)*μ(λ)dλ ,λ=400..790 ),

где I(λ) - спектр излучения от объекта

μ(λ) - спектральная чувствительность прибора (в данном случае глаза)

 

Про модель RGB можно почитать сдесь:

http://ru.wikipedia.org/wiki/RGB

Изменено пользователем Wergilius

Поделиться сообщением


Ссылка на сообщение

Согласно модели стандартного наблюдателя глаз человека имеет 4 стандартизованных фотоприемника (коэффициенты (значения функции цветового соответствия) их есть в таблицах - где-то через 1 нм, где-то через 10 нм, даже ГОСТ был такой). Умножайте интенсивность спектра на значение коэффициента соответствующего фотоприемника стандартного наблюдателя и интегрируйте. Когда-то давно такую программу писал. Проблема может возникать для узкополосых спектров. Тогда вместо таблиц надо использовать интерполяционные формулы (и делать их самому).

Затем просто вычисляете долю X, Y и Z. Есть формулы для перевода в другие системы цветности.

Модель 1931 г. упомянута тут:

http://www.google.ru/url?q=http://ru.wikipedia.org/wiki/%25D0%25A6%25D0%25B2%25D0%25B5%25D1%2582%25D0%25BE%25D0%25B2%25D0%25B0%25D1%258F_%25D0%25BC%25D0%25BE%25D0%25B4%25D0%25B5%25D0%25BB%25D1%258C&sa=U&ei=gT_HTtCoL6vQ4QSx5dAg&ved=0CBMQFjAC&sig2=A4so-r5lPY-BfAPQVOc5Yw&usg=AFQjCNEld-jv-nJAF51xaHDgy5Lwk3f5xQ

Изменено пользователем Jeffry

Поделиться сообщением


Ссылка на сообщение

Я хочу написать функцию на С++, которая, получая пучёк света видимого диапазона (например массив , каждый элемент которого от 400 до 790 принимает значение true\false - есть ли волны этого диапазона в пучке), возвращает GRB значение.

Читал статью про метомерию. Есть 3 графика для R G и B. Вот только я не понял, как из них получить сами значения цвета?Суммировать? У кого какие мысли есть?

Входные данные должны быть в виде массива, но не bool, а float - интенсивность каждой спектральной линии.

 

Затем делается очень простая процедура. Берем графики спектральной чувствительности глаза к красному, зеленому и синему (в виде таких же точно массивов float) и считаем с ними интегральную свертку (aka скалярное произведение в гильбертовом пространстве) - или, попросту, множим эти массивы поэлементно и суммируем:

 

float r = 0, g = 0, b = 0;
for (unsigned i = 0; i < N; ++i) {
   r += in[i] * spr[i];
   g += in[i] * spg[i];
   b += in[i] * spb[i];
}

 

Теперь мы знаем, насколько возбудится в глазу колбочка какого цвета. Это в принципе уже и есть RGB, но не в том цветовом пространстве, в котором работает монитор (не sRGB). Полученный цветовой вектор надо обычным способом помножить на матрицу коррекции, чтобы получить sRGB. Матрицу можно вычислить (вручную, один раз) по тому же алгоритму: найти чувствительности колбочек глаза к каждой из трех компонент монитора (получится матрица 3x3), затем эту матрицу обратить.

Поделиться сообщением


Ссылка на сообщение

Gall, Спасибо огромное за ответы. Вы мне ОЧЕНЬ помогли

Ещё несколько маленьких вопросов -

1)Где взять численное значение интенсивности солнечного излучения? Вообще что такое интенсивность света? Я искал в гугле, но не понял. Это количество фотонов на ед. площадь, через которую они проходят?

2)С матрицей коррекции я не до конца понял. В гугле тоже ничего не нашёл на тему sRB

3)Где бы взять таблицу "Чувствительность цветовых рецепторов". График я видел, но мне нужна именно табличка, чтобы перебить её на С++ в массив

Поделиться сообщением


Ссылка на сообщение

Не за что!

1)Где взять численное значение интенсивности солнечного излучения? Вообще что такое интенсивность света? Я искал в гугле, но не понял. Это количество фотонов на ед. площадь, через которую они проходят?

Почти так. Тут есть путаница в терминологии, поэтому надо уточнить, о какой интенсивности речь. Есть энергетическая интенсивность - количество джоулей суммарной энергии фотонов на единицу площади. И есть нечто, называемое "освещенность" - это взвешенная интенсивность с учетом восприятия глазом каждой длины волны. Освещенность от солнечного света порядка 100000 лк, в комнате около 100 лк. Один люкс (лк) - это люмен на квадратный метр, люмен - это кандела на стерадиан, а кандела - самая загадочная величина. Для зеленого света это 1/683 Вт/ср, а на другие длины волн надо пересчитывать по кривым чувствительности глаза.

 

Спектр Солнца принято брать как спектр абсолютно черного тела температурой 5000-5500 К.

 

2)С матрицей коррекции я не до конца понял. В гугле тоже ничего не нашёл на тему sRB

Ищите "цветовое пространство". Когда мы говорим о составлении цвета из красного, зеленого и синего, мы вольны взять почти любые оттенки этих трех цветов в качестве основных. В зависимости от этого нам надо будет лишь пересчитать интенсивности этих основных цветов - "ввести цветокоррекцию". Если мы хотим пересчитать RGB из одних длин волн в другие, это делается так:

Rновый = Crr * Rстарый + Crg * Gстарый + Crb * Bстарый

и так далее. Но это же умножение 3-мерного вектора на матрицу 3x3, известное из линейной алгебры! И его можно записать так:

 

вектор RGBновый = C * вектор RGBстарый

 

где C - матрица цветокоррекции. Из линейной алгебры известно, что

 

вектор RGBстарый = С-1 * вектор RGBновый

 

В данном случае мы исходно определяем C-1, если возьмем R,G,B монитора и помножим на чувствительности глаза, и нам надо через обращение матрицы вычислить C.

 

Современные мониторы обычно работают в цветовом пространстве "sRGB", зеркальные фотоаппараты и профессиональная аппаратура может использовать "Adobe RGB". Они отличаются длинами волн и взятыми за 1 интенсивностями основных трех цветов - особенно зеленого. Если делаете под обычный монитор (не для полиграфии), используйте sRGB.

 

http://en.wikipedia.org/wiki/RGB_color_space

http://en.wikipedia.org/wiki/SRGB

http://en.wikipedia.org/wiki/Adobe_RGB_color_space

 

 

3)Где бы взять таблицу "Чувствительность цветовых рецепторов". График я видел, но мне нужна именно табличка, чтобы перебить её на С++ в массив

В справочнике по колориметрии. Или возьмите график в крупном масштабе и оцифруйте линеечкой.

Поделиться сообщением


Ссылка на сообщение

Чтоб не создавать отдельную тему, спрошу тут. У лампы накаливания спектр непрерывный, когда ей освещаешь объект - всё видишь нормально. А если лампа светит несколькими монохроматическими цветами, например те же R, G, B, то объект может не поглощать свет с конкретно такими длинами волн и будет казаться чёрным? Люминесцентные лампы сильно цвет искажают. И видеокамеры.

Поделиться сообщением


Ссылка на сообщение

1. Лампа не может светить монохроматическими цветами - это уже не лампа будет, а какой-то лазер тройной.

2. Если объект не будет поглощать, он будет не черным, а белым.

3. Искажения цвета конечно есть, но все не столь ужасно. Цветовых эффектов полно и независящих от ламп.

4. Видеокамеры иногда нуждаются в гамма-коррекции, это сейчас не большая проблема.

Поделиться сообщением


Ссылка на сообщение

Создайте аккаунт или войдите в него для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!

Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас

×