作者:❄️固態二氧化碳❄️ (主頁)
鏈接:(原創)[短小精悍系列]RGB(RGI/RGV)顏色明度(亮度)計算公式 (又稱灰度公式,彩色照片轉黑白照片時能派上用場) - 固態二氧化碳的博客 - CSDN博客
來源:博客園
發表時間:2019年09月25日 10:37:23
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
先上公式:
\(L=k\sqrt[2.2]{(\frac{R}{255})^{2.2}+(1.5\frac{G}{255})^{2.2}+(0.6\frac{B}{255})^{2.2}}\)
其中\(k=\sqrt[2.2]{\frac{1}{1+1.5^{2.2}+0.6^{2.2}}}≈0.547373\)
L取值范圍為\(0\sim1\),黑色\(L=0\),白色\(L=1\)
友情提示:現在網上大多數計算公式(諸如0.30R+0.59G+0.11B之類的)都是錯的,因為它們連最基本的gamma校正都沒考慮進去,結果自然會錯得十分離譜。看到這類形式十分簡單,只有加法和乘法,連根號都不帶的公式,一律都是錯的!
目前絕大多數電腦,手機,平板,電視等電子設備使用sRGB色彩空間。觀測表明,在大部分使用sRGB色彩空間的顯示器上,紅(R),綠(G),藍(B)三原色的亮度(心理亮度)比為\(\color{#0080FF}1:1.5:0.6\),也就是說,RGB三分量數值為\(1:\frac{2}{3}:\frac{5}{3}\),即\(3:2:5\)時,亮度相等,對應的十六進制值分別為#990000,#006600,#0000FF(不同顯示器顯示效果可能會有偏差,也可能同一台顯示器因為調整過色溫而導致誤差,但大概八九不離十,這里的比值是根據大量顯示器顯示效果統計得來的平均值)。換句話說,三原色在計算機中的值相等時(如均為255),其實際強度大小並非嚴格相等,而是存在一定的比例關系。
至於原因嘛,那就是三原色配比成白色的問題了,又叫白平衡。如果三原色亮度嚴格按照1:1:1配比,那么顏色就會明顯偏冷,就像這樣一個顏色:#DDCCFF,一種偏藍紫色的顏色,這是因為我們對冷色光(高頻光,藍紫色光)太過於敏感,而對暖色光(低頻光)敏感性則略遜一籌,這里所說的敏感指的是光對色度的影響,即混入一種光后對色度圖上顏色坐標的影響程度。打個很簡單的比方,紅色和藍色疊加得到的紫色更偏向於冷色(藍色),而不是暖色(紅色)。再比如,白色中缺少一點點紅色的冰藍色(#CCFFFF)和白色中缺少一點點藍紫色的淡黃色(#FFFFCC),明顯前者更接近白,后者則太黃,如果放在手機上面,兩者就是所謂的"冷屏"和"暖屏",說得不好聽一點,后者就是傳說中的"shi黃屏"。
所以為了避免這個問題,三原色的配比不能嚴格按照1:1:1,而是紅綠色要比藍紫色多,才能保證生成完美的白色,也就是不冷不暖的白色,因為人眼對於冷色太過於敏感。這也就導致了RGB(RGI/RGV)中三原色的亮度不一致,綠色亮度比較大,紅色適中,而藍紫色(靛色)則明顯偏小。為了合成出真正的藍色,我們需要在藍色分量(B)中加入適量的綠色分量(G),這樣既把原來偏紫的藍變正宗了,而且亮度也變大了。所以在RGB(RGI/RGV),正宗的藍色對應的色相為210°,而不是240°,這一點我在之前的文章已經說過了。
最后一點,剛才我所說的"亮度"指的都是心理亮度,但是還有一種亮度,稱為"物理亮度",這是怎么回事呢?原來,物理亮度由功率決定,與功率成正比,而人眼對亮度的感知與功率並不成正比,而是冪函數的關系,這個函數的指數我們通常稱作伽馬(gamma)值,符號為γ。如果我們把物理亮度記為\(L_p\),心理亮度記為\(L\),則有\(L_p=L^γ\),而大量研究表明,這個伽馬值通常在1.8~2.6之間,在絕大多數發光設備上,這個值取的是2.2,所以我們有\(L_p=L^{2.2}\)。而我們常說的RGI三分量的大小對應的是心理亮度,雖然有極少數用物理亮度表示,通常把前者稱為Gamma(非線性)空間,后者稱為線性空間。關於線性和非線性空間的知識,我會在以后的博文重點講解的。
而色光亮度的合成是遵循物理亮度(線性空間)的,並非心理亮度,而最后合成得到的亮度又要換算成心理亮度。而之前我們有,RGB三原色心理亮度比為\(1:1.5:0.6\),故物理亮度比為\(1:1.5^{2.2}:0.6^{2.2}\)。因此對於某種顏色的亮度(心理亮度),我們有
規定白色的亮度為1,則\(1=k^{2.2}(1+1.5^{2.2}+0.6^{2.2})\)
解得\(k=\sqrt[2.2]{\frac{1}{1+1.5^{2.2}+0.6^{2.2}}}≈0.547373\)
將前面的長式子兩邊開2.2次方,得
噫,大家發現了什么嗎?如果把\(\frac{R}{255}\),\(1.5\frac{G}{255}\),\(0.6\frac{B}{255}\)看成一個整體,這公式和勾股定理長得賊像!只不過指數由2變成2.2(伽馬值),外面還有個系數k沒乘進去。而這三個整體,把根號外面的k乘進去后,反映的正是三個分量對應的亮度!看來,光的(心理)亮度的合成是遵循"勾股定理"的,只不過指數變成了2.2,我們姑且把它稱之為"類勾股定理"吧!(其實,在數學上,這個玩意叫范數,通俗地說,指數為p的"勾股定理"對應的就是p-范數。比如說歐氏幾何的勾股定理就是2-范數,而剛才所說的亮度的合成,就是2.2-范數)。利用這個定理,我們就可以解釋為什么紅色(\(L=k\))和綠色(\(L=1.5k\))合成的黃色的亮度並不是\(2.5k\),顯著高於綠色,而是\(1.75345k\),與綠色亮度相差無幾,類比勾股定理,你就可以很直觀地去理解它了。
在以后的文章中,我還會繼續利用"勾股定理"這個思想去解決關於亮度的問題的。
最后,附上算法代碼(C語言)。共兩個函數,lightness函數返回亮度值(0~1),rgb2gray函數返回灰度值(0~255)
#include <math.h>
typedef unsigned char uint8;
const float k=0.547373141f;
float lightness(uint8 R,uint8 G,uint8 B)
{
return pow(pow(R/255.0f,2.2f)+pow(G/170.0f,2.2f)+pow(B/425.0f,2.2f),1/2.2f)*k;
}
uint8 rgb2gray(uint8 R,uint8 G,uint8 B)
{
return (uint8)(pow(pow(R,2.2f)+pow(G*1.5f,2.2f)+pow(B*0.6f,2.2f),1/2.2f)*k);
}
將彩色照片轉換成黑白照片時,只需將每一個像素點的亮度值乘上255即可得到其等價灰度值,即黑白照片中RGB三個分量共同的值