跳轉到內容

JPEG - 想法與實踐/顏色成分

來自華夏公益教科書

BMP 格式

[編輯 | 編輯原始碼]

在計算機中,顏色由其三種原色的組成來確定,它們的比例以位元組來衡量,即從 0 到 255 的整數。因此,一種顏色對應於一個三位元組組,稱為RGB 三元組圖片是 RGB 三元組的矩形矩陣。如果圖片的寬度為 w,高度為 h,則顏色值(RGB 三元組)由 (i, j) 對索引,i = 0, ..., w-1, j = 0, ..., h-1,使得左上角的座標集為 (0, 0)(即,縱座標向下測量)。圖片佔用 3wh 位元組,可以透過將由 3w 位元組組成的 h 條水平線依次儲存在記憶體塊中來儲存。透過將記憶體塊(直接)傳輸到螢幕上以顯示圖片的過程稱為點陣圖

(在Windows 的點陣圖過程中,要求水平線上位元組的數量必須能被 4 整除,這意味著記憶體塊中的線段可能需要增加 1、2 或 3 個位元組,通常用零填充。)

圖片可以永久儲存在一個檔案中,該檔案由以這種方式排列的資料位元組組成,並附帶一個標頭,用於指定檔案型別和圖片的尺寸。對於WindowsBMP 檔案格式(BMP = 點陣圖圖片)來說,就是如此。BMP 檔案以一個 54 位元組的標頭開始。由於 BMP 檔案中的資料與繪製點陣圖所使用的方式完全一致,因此可以直接從讀取檔案中繪製圖片 - 而不涉及 RAM 記憶體,也不使用除基本算術運算之外的任何其他運算。

(BMP 檔案的標頭分為 17 個塊,每個塊由一個、兩個或四個位元組組成。兩個位元組確定一個從 0 到 2562 - 1 = 65535 的整數,稱為,四個位元組確定一個從 0 到 2564 - 1 = 4294967295 的整數,稱為雙字。BMP 標頭的頭兩個塊是位元組 66 和 77,與字元 'B' 和 'M' 相對應,指定檔案型別。塊 8 和 9 是雙字,分別表示寬度和高度,塊 10 和 11 是字,通常分別設定為 1 和 24(= 每種顏色的位數),塊 7 是一個雙字,通常設定為 40。除塊 4 和 5(它們是字)之外的其他塊都是雙字,所有這些塊都可以設定為 0,因為它們通常不會被讀取檔案的程式讀取。)

資料壓縮

[編輯 | 編輯原始碼]

BMP 檔案格式和要傳輸到螢幕上的點陣圖記憶體塊對於計算機和程式設計師來說都是簡單的任務,但這些儲存圖片的方法佔用的記憶體空間很大:一張 1000x750 畫素的圖片佔用 3x1000x750 = 2.2 Mb。這在圖片的製作過程中或儲存相對較少的圖片(需要儘可能高的質量)時可以暫時接受,但對於包含數百張圖片的資料夾或電影或來自網際網路的傳輸來說,如此大的空間是不可接受的。人們會立即想到,不可能讓數字化的資料佔用更小的空間,因為位元組成的材料無法像照片底片那樣縮小。但是,數字化資料集由位元序列組成,這些序列可以被更短的序列替換 - 如果存在重複,則重複的部分可以被充當其型別和重複次數的符號的序列替換。如果資料是某個固定集合(例如數字)的元素的副本,那麼我們可以為集合的元素分配位元序列,使得使用最頻繁的元素分配最短的序列。此外,如果資料集的元素是大小變化很大的數字,那麼我們可以嘗試刪除數字之間的空白,而不是為每個數字分配相同的空間。當然,這不能隨便進行,因為(由於沒有第三個位元)我們需要一個工具來分離對應於數字的位元序列。然而,我們可以插入充當程式碼的位元序列。

只有非負整數可以直接數字化,方法是寫出它的二進位制數字表達式

n = cm2m + ... + c222 + c12 + c0

其中 c0, ..., cm 是位元:0 或 1 - 我們對序列進行排序,使得最高有效位排在最前面。如果數字是理數或實數,我們必須以某種方式將其表示為兩個非負整數的組合。要插入的程式碼可以選擇與自然數一一對應,並且使得分配給程式碼的自然數是後續非負整數的位數。程式碼必須選擇得當,使得最常用的自然數(表示位數)具有最短的程式碼,並且還能讓我們確定程式碼何時結束。

當資料需要使用時(例如要顯示圖片),壓縮資料集會經過解碼過程,留下與原始資料集完全相同的資料集。幾乎所有影像檔案格式都支援以這種方式壓縮資料。這種技巧當然也用於 JPEG 過程,但在這個過程中,資料在壓縮之前會先進行修改:首先轉換顏色值,然後透過將新的值除以某些數字並進行舍入來減少新的值。最後一個過程稱為量化,它可能會引入(很小的)偏差。

基礎顏色是純色,它們是飽和度最高的“最強”顏色。純色構成一個迴圈色標

因此,純色由一個角度決定。任何與灰度色不同的顏色都是混合了唯一確定的純色和灰度色而得到的。純色的亮度並不相同:其中三種的亮度低於其他顏色,它們是原色:純紅、純綠和純藍,分別對應於 0 度、120 度和 -120 度。任何不是原色的純色都位於兩種原色之間,是由其中最接近的原色與另一部分的混合而得到的。如果我們將三種原色混合在一起,就會得到白色 - 亮度最高的顏色。由此我們可以看到,每種顏色都是透過混合三種原色得到的,每種原色都或多或少地變暗。這就是 RGB 表示法。我們通常以位元組來衡量三種顏色的數量,這樣 255 就對應於原色,而 0 就對應於黑色。

(我們可以透過以下方法找到與顏色 C(與灰度色不同的顏色)相關的純色:透過從白色中減去 C 的 RGB 值,我們得到顏色 C1,其 RGB 三元組為 (255-R, 255-G, 255-B)。如果我們假設藍色在該顏色中所佔的比例最大,則 C1 = β C2,其中 β <= 1,而顏色 C2 是藍色所佔的比例為 255 的顏色。透過從白色中減去 C2,我們得到顏色 C3,如果我們假設紅色在該顏色中所佔的比例最大,則 C3 = α C4,其中 α <= 1,而純色 C4 是紅色所佔的比例為 255,藍色所佔的比例為 0 的顏色。這是與 C 相關的純色,我們可以透過根據 α 與黑色混合,根據 β 與白色混合來得到 C。)

YCbCr 值

[編輯 | 編輯原始碼]

然而,RGB 顏色表示法有一個缺點:三個值具有同等的重要性。我們更希望有一種三元組表示法,其中一個值(第一個值)比另外兩個值更重要,因為這樣,在量化過程中,我們就可以允許另外兩個不太重要的分量有更大的偏差。這種表示法很容易想象,如下面的四張圖片所示:我們可以讓三元組中的第一個值為三個 RGB 值的平均值,從而表示顏色的強度(並給出相應的灰度圖片),而讓另外兩個值構成“顏色增量”。我們將顏色(RGB 三元組)想象成一個邊長為 256 的立方體的整數點,該立方體以三個正座標軸為邊,原點位於對應於黑色的角落。在這個立方體中,灰度色位於對角線上,我們將對角線作為第一個軸。我們可以讓另外兩個座標軸垂直於對角線且相互垂直,但為了得到一個簡單的變換,我們讓它們位於 B-G 平面和 R-G 平面。注意,新的座標系意味著最後兩個顏色值可以為負數。我們選擇單位使得第一個座標用位元組來衡量,另外兩個座標用帶符號位元組來衡量:從 -128 到 127 的整數。新的座標三元組透過線性變換與 RGB 三元組相關聯。

我們稱這種新的表示為顏色的 YCbCr 值。Y 代表亮度(或亮度),C 代表色度:Cb 代表藍色色度,Cr 代表紅色色度。我們的假設意味著存在引數 kb 和 kr,使得線性變換及其逆變換由下式給出

Y = kr∙R + (1 - kr - kb)∙G + kb∙B
Cb = ½(B - Y)/(1 - kb)
Cr = ½(R - Y)/(1 - kr)
R = Y + 2(1 - kr)∙Cr
G = Y - (kb∙(B - Y) + kr∙(R - Y))/(1 - kb - kr)
B = Y + 2(1 - kb)∙Cb

我們可以看到,如果一種顏色是灰度顏色,也就是說,如果 R = G = B,那麼 Y 就是這個數字,而 Cb 和 Cr 為零。在數學上,將 kb 和 kr 設定為 1/4 比較自然,因為變換將獲得一個簡單而自然的形式

Y = R/4 + G/2 + B/4
Cb = -R/6 - G/3 + B/2
Cr = R/2 - G/3 - B/6
R = Y + (3/2)Cr
G = Y - (3/2)(Cb + Cr)/2
B = Y + (3/2)Cb

然而,在 JPEG 實現中——我們在這裡以它為指導——引數 kb 和 kr 被設定為 0.144 和 0.299,並且使用這些值,公式變為

Y = 0.299∙R + 0.587∙G + 0.114∙B
Cb = -0.168736∙R - 0.331264∙G + 0.5∙B
Cr = 0.5∙R - 0.418688∙G - 0.081312∙B
R = Y + 1.402∙Cr
G = Y - 0.3441∙Cb - 0.71414∙Cr
B = Y + 1.772∙Cb

這意味著座標軸是:對角線、G-B 平面上的直線 (-0.34, 1.77) 和 R-G 平面上的直線 (1.40, -0.71)。由於兩個色度座標的範圍在 [-128, 127] 區間內,我們必須在它們中新增 128 以獲得位元組,以便我們可以繪製圖像在座標軸上的“投影”。現在,我們不再是透過紅、綠、藍比例來組成影像,而是透過灰度比例、藍綠比例和紅綠比例來組成影像

由於我們希望我們的數字(整數)儘可能小,因此我們從 Y 值中減去 128,以便它像 Cb 和 Cr 一樣成為一個有符號位元組。

華夏公益教科書