關於色域的學習筆記(轉載)

Form 徐新華

關於色彩空間

色彩是可見光所展現的,不同顏色的物體吸收和反射的波長的光不同,所產生不同的顏色。

色彩做爲現實世界固有的屬性是存在和不變的。

我們利用數學知識對色彩進行編碼,便是色彩空間的來源,不同的編碼其所指向的顏色都是唯一存在的,因此色彩空間都是可以互相轉換的。其只是不同的數學變現形式而已。

例如:我用0-255表現紅色,也可以用0.0-1.0表現紅色,他們之間是可以互轉的。

不同精度表現的顏色數量也不一樣,如果你只用1個bit位表現顏色,那麼這個世界就只有兩種顏色0和1即非黑即白,如果你用8個bit位表示顏色,就有256種顏色,呵呵就是最開始所說的256色。

現實世界是連續的,我們的數學表徵是離散的。我們用有限的數字表示無限的顏色,這樣數字精度越大所表現的顏色就越多,就越接近真實的世界,如果色彩還原系統如電視能支持這麼大的精度,則越接近真實。

那麼是否是精度越高越好了,這時候我們就需要和現實我們能做到的進行妥協。

1)顯示設備能夠顯示的精度

2)我們傳輸的帶寬和cpu的處理能力,處理32bit和處理8bit對帶寬和處理器要求有天大的區別。

如何解決這個問題?

科學家們對人眼就行測量和觀察得出人眼的一些特性。

1)人眼有視錐細胞視杆細胞來區分顏色,

2)人眼有視覺暫留作用:這個作用我們就可以用dither抖動來模擬更多的顏色,通過快速交換不同的顏色來欺騙眼睛。

3)人眼對圖像的認知是非均勻和非線性的:實際上壓縮算法充分利用這一點。很多顏色人眼是區分不出差別的。呵呵舉個簡單的例子,1.74m和1.75m高的兩個人站在一起感覺兩個人差不多看不出差別,1.73和1.74也看不出差別,但1.73和1.75放到一起就有差別了。類似對於顏色採樣的精度在一定區間,人眼就認爲是連續的,準確的。

4)人眼對380nm-780nm不同波長的顏色光有不同的敏感度,有色光初中我們就學到用三棱鏡可以分離爲紅橙黃綠青藍紫,在光譜上人類對綠光感覺最靈敏,向兩邊遞減,根據這個特性科學家發明了yuv色彩空間進行編碼,數字量化的表示是ycbcr 亮度+藍色偏差+紅色偏差來表示顏色。

CIE 1931 色域色度圖
在這裏插入圖片描述

如何看CIE1931色域圖:

從自然界看色彩是由不同波長的光所發出的,但我們可以通過混合不同比例的光來產生其他顏色,譬如rgb是最常用的基準色,當然也可以採用其他顏色組合。

我們的色域空間CIE1931也是基於RGB三原色定義的,被成爲XYZ色彩空間,X代表R,Y代表G,Z代表B,通過不同比例混合這幾種色光來產生所有顏色。

我們定義X+Y+Z=1即三種顏色的比例之和爲一。

那麼基於XYZ構建的幾何平面上表示了所有的顏色。由於3維圖形不好看。我們從X+Y+Z=1數學等式可以看到只要知道xy就能得出z,故我們直接在二維平面上構建我們的色域圖如上圖所示。

從圖上觀察可以看出x比例加大即R色加大,y比例加大,代表綠色加大,xy較小即z變大blue變大。

色域圖邊界我們看到的數字是純色可見光的波長。下面的直連線外爲不可見光,紅外線和紫外線。

白色點即xyz比例相當的點即0.33左右,就在D65位置。即x和y座標爲0.33左右的位置。

這是標準的線性空間定義的顏色,隨着採樣精度的提高,所能表達的顏色數量就越多。

我們提到的現實科學中使用的各種的色彩空間是由於我們無法用更高的精度來表達顏色,能表達的顏色的個數非常有限,所以很多標準都是爲了不同的領域定義了一個顏色子集,這樣就形成了不同的色彩空間標準。

譬如:

計算機使用的RGB色彩空間,他使用8bit位描述每種基色,他所能描述的色彩空間相對較小。

基於電視的YUV色彩空間601,709 2020,2020空間用10bit到16bit來描述顏色所覆蓋的XYZ色彩空間的色彩就更多。電視黑白電視只要亮度爲了兼容,同時對色度敏感度小,可以減少色度的數量便於傳輸。

基於印刷行業的CMYK色彩空間由於顏料調色,這種方式更方便顯示和印刷才能一致。

sRGB色彩空間,其代表的數值已經做過gamma校正了等等不同目的的色彩空間。

Gamma

現在的顯示設備大部分都是非線性的,即給出的電壓激發熒光粉產生亮度不是線性比例y=kx的,而是指數形式的關係 y=x^ϒ ϒ(gamma)通常取2.2這也是sRGB空間的gamma取值,實際上每個顯示設備gamma值可以不同(跟顯示器實現方式有關)。

在這裏插入圖片描述

y=x^2.2(顯示器的gamma曲線)橫座標是電信號,縱座標是亮度信號。

例如,我們想顯示0.2的亮度,如果是線性的,我需要給0.2的電壓(我們給的電平pcm),這樣我們預期的給定值和實際值相符,就能正常顯示對的圖像了,可惜你給的0.2v的電壓在物理特性上只能才生0.05的亮度,這樣對於這個像素點就和我們的預期有差距了,這時候怎麼辦了,聰明的科學家就想到了我這個像素要0.2的亮度,給0.2v不行,我就給0.4v

這樣就修改我們的圖像像素數據值對於0.2的亮度我們給0.4v的數據,這樣就是gamma校正。

我們要理解gamma是爲了補償顯示器還原色彩不準確所引入的,顯示器用來激發顯示亮度的電壓和亮度不是線性正比例關係,故顯示器必須做gamma修正,使得顯示器能正確的顯示信號源給定的顏色值。

實際上顯示器做了gamma修正後基本上就能正確反應我們信號源給定的顏色值了,但爲什麼有些視頻播放器還要做gamma校正了。這是因爲爲了討好人的眼睛,根據人的眼睛對亮度信號的不同敏感度來修改每個像素值,對於yuv色彩空間來說,gamma只修改的是y分量即亮度值,而不修改色度的uv分量。

人眼睛對於亮信號更敏感,調整gamma,如果小於1圖像曲線是x的0.n次方,從圖像看會導致壓縮了暗部,拉大了亮部,如用255個數字表示灰階,如果正常是16個數字表示暗部,那現在可能就只有8個了,導致暗部的區分度過低,暗部細節丟失,反而表達亮部的數字變多了,亮部信號顯示更多。

通常我們不應該在軟件上調整gamma,這個是顯示器的固有屬性,而且每個人對於顏色的感知並不相同,有的人認爲好,有的人認爲失真了,所以正常情況下,應該由用戶自己調整。

關於D3D中一些紋理類型的說明

DXGI_FORMAT_R8G8B8A8_TYPELESS = 27,

DXGI_FORMAT_R8G8B8A8_UNORM = 28,

DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 29,

DXGI_FORMAT_R8G8B8A8_UINT = 30,

DXGI_FORMAT_R8G8B8A8_SNORM = 31,

DXGI_FORMAT_R8G8B8A8_SINT = 32,

DXGI_FORMAT_R10G10B10A2_UNORM = 24,

DXGI_FORMAT_R16G16B16A16_UNORM = 11,

這些紋理都有些不同的後綴其含義說明如下:

SNORM: S代表signed 有符號 NORM:代表歸一化

UINT: U代表unsigned 無符號 INT代表正常的正說沒有歸一化,如果是8bit就代表0-255

SRGB:代表非線性的色彩空間,實際上就是標準色彩空間,這個空間是正常rgb描述的空間做了gamma=2.2的變換。我們基本不用,除非我們加載的紋理是sRGB色彩空間的圖片。

有符號的歸一化就是【-1.0, 1.0】無符號歸一化就是【0,1.0f】

SINT ==>[-128,127]

UINT ==>[0,255]

UNORM ==>[0.0, 1.0]

SNORM ==>[-1.0, 1.0]

FLOAT :如果是16位的浮點其表示的值含義是1bit的符號位,5bit的指數位,10bit的小數位。

32位的浮點數,1位符號位,8位指數位,23位小數位

色彩空間格式的解釋:

DXGI_FORMAT_R8G8B8A8_UNORM:這種格式的紋理資源在資源中被解釋成無符號的整數即[0,255],但在shader中被解釋爲[0.0,1.0],所以我們寫着色器shader程序的時候注意他的取值範圍。

對於帶有歸一化後綴的紋理他們在着色器和資源中被解讀成不同的數值。

DXGI_FORMAT_P016:每通道16位平面YUV 4:2:0視頻資源格式。該視頻資源格式的有效亮度數據視圖格式爲DXGI_FORMAT_R16_UNORM和DXGI_FORMAT_R16_UINT。該視頻資源格式的有效色度數據視圖格式(寬度和高度均爲亮度視圖的1/2)是DXGI_FORMAT_R16G16_UNORM和DXGI_FORMAT_R16G16_UINT

DXGI_FORMAT_P010:每通道10比特平面YUV 4:2:0視頻資源格式。該視頻資源格式的有效亮度數據視圖格式爲DXGI_FORMAT_R16_UNORM和DXGI_FORMAT_R16_UINT。運行時不強制最低6位是否爲0(假設該視頻資源格式是使用16位的10位格式)。如果需要,應用程序着色器代碼必須手動強制執行此操作。從運行時的角度來看,DXGI_FORMAT_P010與DXGI_FORMAT_P016沒什麼區別。

P10/P12/P16沒有本質區別都是用16bit表示顏色值,只是精度不同10bit低位的6bit沒有意義,即顯示設備沒有那麼高的精度,前面10bit相同後面的不同,對於顯示器也認爲是同一種顏色。

關於ITU-R BT.601 709 2020標準

BT:broadcast Television

這些標準都是國際電信無線電通信部門爲電視制定的圖像色彩編碼標準。用以確保電視從節目製作到播放能夠正常的顯示正確的顏色和圖像。

每種色彩空間標準所覆蓋的顏色數量不同其都是CIE 1931基於XYZ色彩空間所表示的顏色的子集。

這幾種色彩空間都是基於YUV的其和RGB色彩空間存在着轉換關係,而且最接近人的真實感知。人眼對亮度更敏感對色度相對不敏感,哈哈更有人是色盲,區分不了顏色。

YUV420 容量只有444的一半,由於人眼敏感度的原因並不能看出顏色有什麼差別,這樣就爲傳輸和存儲省了很大的空間。

對於8bit位的YUV,Y區間爲[16,235] , UV[16,240] 爲什麼不是0–255了,是因爲crt電視的時候是無法到達0度黑的。

對於10bit的yuv,y[64, 940], uv[64, 960],沒多一個數達標所能表達顏色的階數就多一個,顏色分辨率就更大,如果只有2bit我們只能表達4中顏色,8bit就可以256種了。顏色細分不夠就會出現條帶banding。

Dither的出現原因,由於想表達更多的顏色,譬如想表達10bit灰階的顏色,但我們只有8bit的數據,這時候就可以通過抖動來模擬更多的顏色了,帶來的後果是降低了分辨率,譬如用2個像素來表達原來的一個像素,2個像素相當於用16bit來描述顏色了,色彩所覆蓋的就更多,但分辨率減少了一半。實際電視是顯示不了這麼多顏色的,但通過這種方式欺騙眼睛,這種情況在顯示設別能力不足,但節目源有更多的bit深度的情況下有用。實際上沒有卵用,這種情況並不多。

區別:

601/709/2020他們用來轉變到rgb的比例係數並不相同,這也是根據顯示設備的能力由於能夠更多的表達顏色,這樣調整係數使得顏色分佈更合理。

601標準用8bit位深。

709通常爲8bit也可以更多位深。720P 1080P

2020 10bit/12bit/16bit,並且分辨率有要求必須是4K或8K分辨率。並且還只能是逐行。

HDR的時候需要創建P010的紋理,即顯示設備要支持非RGB輸出

我們在使用YUV色彩空間的時候最終我們要轉換成RGB紋理輸出,我們的電視在不支持10bit的情況下通常只能是8bit的rgb,我們經常看到有rgb輸出pclevel[0,255], tvlevel[16-235],現在的電視,投影爲了兼容pc基本上都是pclevel了,而且表達的顏色也更多。只要老的一些電視纔有tv level這個。

所以我們的視頻輸出rgb都是pc level給投影和電視。

10bit的內容要在8bit的顯示設備輸出,如果要有更好的效果可以考慮dither,特別是針對4k電視,但節目源是1080P的情況。


作者:徐新華
原文:https://blog.csdn.net/xuxinhua/article/details/82502836

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章