Преобразование цвета RGBW в стандартное представление RGB/HSB

Я создаю интерфейс для управления освещением в системе домашней автоматизации. Мне удалось без особых проблем управлять стандартным включением/выключением и диммируемым освещением для различных поставщиков, но теперь я столкнулся с проблемой, связанной с RGB-подсветкой.

В настоящее время я использую светодиодную ленту RGBW — в частности, я работаю с недорогим источником света RGBW: свет состоит из четырех светодиодов, и каждым светодиодом можно управлять отдельно.

Чтобы быть более ясным, я работаю над некоторым кодом С#, который должен извлекать текущий выбранный цвет и отображать его в пользовательском интерфейсе, а также позволять пользователю указывать новый цвет для света. Для установки цвета и его получения я должен использовать поставщика команд, который позволяет мне отправлять и получать команды через веб-службу.

Провайдер работает с цветами RGBW — используются четыре компонента для красного, зеленого, синего и белого. Чтобы представить текущий цвет света в моем интерфейсе, я хотел бы преобразовать цвет RGBW, возвращаемый службой, в более стандартную схему RGB/HSB.

При поиске в Интернете единственная ссылка на преобразование цвета, которую я нашел (исключая образец С++ для преобразования rgb в rgbw, который, насколько я понимаю, должен иметь некоторую серьезную ошибку), — это статья, в которой показано преобразование из HSI в RGBW, которое противоположное тому, что мне нужно: ссылка здесь

Я ищу некоторое представление о том, как я могу добиться этого преобразования (или простое объяснение, почему это невозможно). Насколько я понимаю, преобразование из RGB в RGBW является произвольным — одно значение RGB может быть представлено как несколько значений RGBW, но противоположное преобразование должно быть однозначным. Также обратите внимание, что пока я использую С#, не стесняйтесь ссылаться на алгоритмы и на другом языке - проблема не в языке, проблема в том, что я не знаю математики для преобразования цвета.


person SPArcheon    schedule 14.01.2014    source источник


Ответы (3)


Я просматривал ответ, предложенный Роберто, но во многих случаях цвета казались более тусклыми и ненасыщенными. Взятие примера RGB = (255,255,2) приводит к RGBW = (128,128,1,2).

Копая дальше, кажется, что в статье Чула Ли есть ошибка в уравнении для K. Уравнение взято из статьи Лили Ванг («Компромисс между яркостью и цветом в дисплеях RGBW для использования на мобильных телефонах») на самом деле:

K = (Wo + M)/M

Обратите внимание, что это заглавная М, а не строчная м. Учитывая это изменение, вам также не нужен Q, так как он правильно масштабируется по своей природе. Использование нового K в том же примере RGB = (255,255,2) приводит к гораздо более разумному RGBW = (255,255,0,2).

Собираем все вместе:

M = max(Ri,Gi,Bi)
m = min(Ri,Gi,Bi)

Wo = if (m/M < 0.5) use ( (m*M) / (M-m) ) else M 
K = (Wo + M) / M
Ro = floor[ ( K * Ri ) - Wo ]
Go = floor[ ( K * Gi ) - Wo ]
Bo = floor[ ( K * Bi ) - Wo ]
person cobra18t    schedule 31.12.2019

Как преобразовать RGB в RGBW описано в пункте 2.1 следующей статьи.

http://www.mirlab.org/conference_papers/International_Conference/ICASSP%202014/papers/p1214-lee.pdf

Думайте о своих светодиодах как об огромном пикселе. Ответ Оливера использует Wo = min(Ri,Gi,Bi), что является дешевым в вычислительном отношении и просто работает. В этом документе объясняются другие альтернативы для минимизации энергопотребления, что хорошо для проекта домашней автоматизации. Я также занимаюсь проектом домашней автоматизации со светодиодами OpenHAB, Arduino и RGBW, и, с одной стороны, предложенная альтернатива была бы хорошей, с другой стороны, огромный LUT просто не работал бы и преобразовывал все значения на arduino 8er. Я бы посоветовал вам попробовать исправить значения RGB, используя не столь энергоэффективную технику, как указано в статье:

Предполагая, что Ri, Gi, Bi являются входными данными цвета, целыми числами от 0 до 255, поэтому Q = 255, а ваши выходные данные — Wo, Ro, Go и Bo со значениями от 0 до 255:

M = max(Ri,Gi,Bi)
m = min(Ri,Gi,Bi)

Wo = if (m/M < 0.5) use ( (m*M) / (M-m) ) else M 
Q = 255
K = (Wo + M) / m
Ro = floor( [ ( K * Ri ) - Wo ] / Q )
Go = floor( [ ( K * Gi ) - Wo ] / Q )
Bo = floor( [ ( K * Bi ) - Wo ] / Q )

Перед реализацией потренируйтесь в электронной таблице, поэкспериментируйте с Wo = m, m^2 и -m^3+m^2+m, исправьте значение Wo с помощью правильного Qw, и вы удивитесь, что простое решение без коррекции — это не то, что нужно. можно было бы ожидать, и что другие ответы не сильно различаются. Проверьте на бумаге результаты искажения цвета, я полагаю, что если вы не исправите значения RGB, вы получите размытые цвета.

person Roberto Cantanhede    schedule 07.01.2015
comment
Спасибо за информацию Роберто. К сожалению, в настоящее время у меня больше нет излучателя света RGBW, но предоставленная вами информация кажется наиболее точной, которую я могу надеяться найти. Обновлю, если/когда я смогу протестировать алгоритм, описанный в этом исследовательском документе. - person SPArcheon; 29.01.2015
comment
Это действительно интересно, спасибо, что поделились. Напоминает мне, что я снова был в школе, пришлось некоторое время смотреть на это ;). - person dps; 16.05.2018

Я знаю, что это довольно старый вопрос, но я смотрю на алгоритм RGB-> RGBW и нашел эту статью, которая, хотя и не является ответом, может помочь?

http://web.archive.org/web/20101008153429/http://www.nouvoyance.com:80/files/pdf/Adding-a-White.pdf

В этом они предлагают одно преобразование для RGB->RGBW просто создать W из min(R, G, B).

  • R -> R
  • G -> G
  • B -> B
  • W -> мин (R, G, B)

Обратное этому (для вашего сценария) было бы просто выбросить W.

  • R -> R
  • G -> G
  • B -> B
  • Вт -> ноль
person Oliver    schedule 17.11.2014
comment
спасибо за вклад, Оливер. Это было общее направление, в котором я начинал проект. Я запутался, пытаясь объяснить менеджерам/pm, что если значение RGB, выбранное в пользовательском интерфейсе, близко к черному, это не будет означать, что устройство вдруг начнет излучать черный свет... - person SPArcheon; 29.01.2015