2017-10-11 71 views
1

的純顏色我有一些RGB LED,並且我想有他們顯示隨機顏色。生成相等的亮度(用於顯示關於LED)

我的第一種方法是從0-360選擇一個隨機色調ħ,創建的形式(ħ,1,1),然後從HSV轉換使用the algorithm given on Wikipedia RGB的HSV色彩。這幾乎做我想要的,但不完全。

的問題是,LED可顯示爲亮或更暗,這取決於色調。無論色調如何,我都希望它始終顯示爲相同的亮度。

因此,舉例來說,藍色爲(0,0,1)在RGB空間,但是青色將是(0,1,1)。如果我們假設所有三個原色都同樣明亮,那麼青色是藍色的兩倍。

我要的是在RGB空間一些地方的藍色將是(0,1,0)和青色爲(0,0.5,0.5),使初選的總和始終是1.0。

我可以使用如下的算法劈東西一起很容易:

  • 送在0和1
  • 之間的值X拾取三原色之一,並將其​​設置爲X
  • 挑選剩下的兩個基色中的一個,並將其設置爲1 - X
  • 將第三小學爲0

我的問題是:有沒有更原則性的方式做到這一點?是否有一些顏色空間的行爲符合我的要求?

結論: @Vincent van der Weele有我需要進行標準化的重要洞察力。而@Stefan Haustein的亮度是另一種說同一件事的方式,同時也爲不同的初選加入不同的權重。但是,這些特定的權重並不適用於我的情況。在實驗中,我選擇了R,G和B的0.3,0.25和0.2的權重。而且在實驗上,我選擇了2.0的伽馬(與原來使用的2.8相反)。這還不完美,但比以前好了很多。我想這只是自然凌亂。

+1

難道你不能把輸出作爲一個後處理步驟,用'R + G + B'除每個'R','G'和'B'來標準化嗎? –

+3

雖然這是一個編程組件,但是顏色和亮度/亮度匹配的整個主題是一個不同的領域,它也帶來了眼睛的受體和整個書本和論文的整個領域。我不認爲這是一個合適的SO問題。 – Rob

+0

問題是(0,1,0)很亮,但(0,0,1)很暗。 –

回答

2

我會帶你光譜的最暗的顏色亮度(=藍色,0.0722)。然後縮放計算出的RGB值,以便生成的亮度與此值匹配。見https://en.wikipedia.org/wiki/Luma_(video)

luma = 0.2126 * r + 0.7152 * g + 0.0722 * b; 
// factor * luma = 0.0722 
factor = 0.0722/luma; 
r *= factor; 
g *= factor; 
b *= factor; 

P.S.有了您的簡化假設,這將是

luma = (r + g + b)/3.0; 
factor = 1.0/(3.0 * luma); 
r *= factor; 
g *= factor; 
b *= factor; 

正火的總亮度,以單個組件(1/3)

+0

我想我在這裏沒有理解的東西。對於許多顏色(例如黃色),藍色分量將爲零。所以這會導致除以零。 – user31708

+0

我指的是你想展示的最黑暗的顏色,一個常數。如果你想讓亮度恆定,所有的顏色都需要有這個亮度。 –

+0

p.s.已經添加了一個代碼片段來說明這更好 –

2

你說的沒錯,組合顏色黃色,青色,品紅是亮度比原色紅色,綠色和藍色亮。您可以通過HSV產生的色調的情節簡單看這個(我相信HSL會看起來是一樣的):

HSV in sRGB

他們是光明的,但不是兩次亮。這是因爲眼睛以power-law function響應光線。將強度取爲the power of 0.43最接近您的眼睛所看到的;這意味着黃色,青色和品紅只會出現1.35倍的明亮度。

還有一個要考慮的因素。 HSV公式產生sRGB值,其具有大約2.2的gamma correction factor-值相對於產生的光量不是線性的。你大概的LED是線性,所以他們會尋找不同:

HSV linearized

呸!很明顯,驅動LED的值需要處於線性色彩空間,而不是sRGB。

爲了保持恆定的亮度,冪律空間中所有顏色的總和將需要保持不變。您可以通過將冪律應用於線性r,g,b強度,然後在總和上縮放r,g,b來實現此目的。採用冪律的倒數將數值恢復爲線性RGB。

下面是一些實際的Python代碼和生成的圖像。將r,g,b值從線性轉換爲sRGB以生成圖像文件,但爲了清晰起見,我將其保留。 srgb2.from_sRGB函數我基於standard sRGB linearity conversions寫了自己。

r,g,b = colorsys.hsv_to_rgb(angle/360, 1.0, 1.0) 
r,g,b = srgb2.from_sRGB([r*255,g*255,b*255]) 
gamma = .43 
r,g,b = r**(1/gamma), g**(1/gamma), b**(1/gamma) 
t = r + g + b 
r = r/t 
g = g/t 
b = b/t 
r,g,b = r**gamma, g**gamma, b**gamma 

HSV normalized

沒有更多的亮點!

+0

是的,我知道伽瑪。我故意將它從我的問題中排除出來(以及紅色,綠色和藍色的不同重量),以關注青色點亮兩個LED而藍色點亮一個的事實。在所有其他步驟之後,我正在執行伽馬校正。不過,我使用的是[2.8](https://learn.adafruit.com/led-tricks-gamma-correction/the-longerfix)。所以你的伽馬值小於1,而我的伽馬值大於1;看來我們中的一個人倒退了。 – user31708

+0

@ user31708是的,稍後當我有更多時間時,我會仔細檢查我的數學。但很明顯,照明兩種顏色需要的亮度比點亮一種顏色的亮度要低,這只是一個提供確切數量的問題。 –

+1

@ user31708我剛剛從零開始重寫了答案,我認爲你會發現它在結果中更容易遵循並且更令人滿意。 –