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

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

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

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

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

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

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

4 ответа

Решение

Как конвертировать 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 Eighter. Я бы посоветовал вам попытаться скорректировать значения 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, у вас будут размытые цвета.

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

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

K = (Wo + M)/M

Обратите внимание, что это заглавная 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 ]

Я знаю, что это довольно старый вопрос, но я смотрю на алгоритм 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
  • W -> ноль

Немного поздно, но все же кажется, что найти инструменты для этого на удивление непросто.

Это репо может сделать эту работу за вас : https://github.com/iamh2o/rgbw_colorspace_converter/

Я написал этот модуль с другом таким образом, чтобы 'цветные' объекты могли быть созданы с помощью нескольких цветовых систем, и объект мог выдавать переводы во все другие цветовые системы, которые он поддерживает, что после БОЛЬШОГО исследования (ключевой элемент является https://www.neltnerlabs.com/saikoled/how-to-convert-from-hsi-to-rgb-white ), мы наконец добились преобразования [HSI / HSL / HSV / RGB / HEX] -> RGBW.

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

И убойная особенность этого модуля заключается в том, что созданными вами цветными объектами можно управлять в нескольких цветовых системах в зависимости от ваших потребностей (различных, в которых вы его создали), и он будет поддерживать все переводы в другие пространства в актуальном состоянии. - и он супербыстрый, у нас еще не было компонента, ограничивающего частоту кадров.

Таким образом, что-то вроде этого было бы циклом через полностью яркую, полностью насыщенную радугу (обратите внимание, как коды RGB и HSV гораздо менее поддаются программным манипуляциям):

      from rgbw_colorspace_converter.colors.converters import RGB

color = RGB(255,0,0)

ctr = 0

while ctr < 10:
     color.hsv_h += .1
     print(f"HSV:{color.hsv}  RGB:{color.rgb}  HSI:{color.hsi} HEX:{color.hex}")
     ctr += 1

# "H" in hsv is actually expressed in 360 degrees, and it is cylindrical. We've normalized it to being between 0-1 (so H=0=H=1 - both are red)
HSV:(0.0, 1.0, 1.0)  RGB:(255, 0, 0)  HSI:(0.0, 1.0, 0.33333) HEX:#ff0000
HSV:(0.1, 1.0, 1.0)  RGB:(255, 153, 0)  HSI:(36.0, 1.0, 0.533328) HEX:#ff9900
HSV:(0.2, 1.0, 1.0)  RGB:(203, 255, 0)  HSI:(72.23529411764707, 1.0, 0.5986868235294117) HEX:#cbff00
HSV:(0.3, 1.0, 1.0)  RGB:(51, 255, 0)  HSI:(108.0, 1.0, 0.399996) HEX:#33ff00
HSV:(0.4, 1.0, 1.0)  RGB:(0, 255, 102)  HSI:(144.0, 1.0, 0.46666199999999997) HEX:#00ff66
HSV:(0.5, 1.0, 1.0)  RGB:(0, 255, 255)  HSI:(180.0, 1.0, 0.66666) HEX:#00ffff
HSV:(0.6, 1.0, 1.0)  RGB:(0, 102, 255)  HSI:(216.0, 1.0, 0.46666199999999997) HEX:#0066ff
HSV:(0.7, 1.0, 1.0)  RGB:(50, 0, 255)  HSI:(251.76470588235296, 1.0, 0.39868882352941176) HEX:#3200ff
HSV:(0.8, 1.0, 1.0)  RGB:(204, 0, 255)  HSI:(288.0, 1.0, 0.599994) HEX:#cc00ff
HSV:(0.9, 1.0, 1.0)  RGB:(255, 0, 152)  HSI:(324.2352941176471, 1.0, 0.5320208235294118) HEX:#ff0098
HSV:(1.0, 1.0, 1.0)  RGB:(255, 0, 0)  HSI:(0.0, 1.0, 0.33333) HEX:#ff0000

Другие вопросы по тегам