前往
大廳
主題

JPEG壓縮原理詳解

黛安娜 | 2020-12-31 16:54:30 | 巴幣 1116 | 人氣 2999

圖片在未經壓縮前為點陣圖像
因為光的三原色為RGB,紅色Red、綠色Green、藍色Blue組成
所以我們會將點陣圖的通道設計成RGB三個通道
RGB點陣圖轉JPEG分為以下步驟:
1. RGB轉YUV
2. 分割YUV成多個8×8區塊
3. DCT離散餘弦轉換
4. 品質參數降採樣
5. DC DPCM差值壓縮編碼
6. AC Zigzag之字形排列RL編碼
7. DC Huffman查表
8. AC Huffman查表

JPEG轉RGB則是將所有順序反向即可。
1. RGB轉YUV
        (來源:https://zh.wikipedia.org/wiki/YUV)
YUV又名YCbCr,Y代表明暗度(上圖第2格),U為色度(上圖第3格),V為濃度(上圖第4格)。
RGB轉YUV的方式很容易,就是將每個像素的RGB數值透過公式轉成YUV。
可以看到上圖的YUV中的U和V沒有Y來的明顯易分辨,所以比較容易進行壓縮,若不作此步驟,也就是RGB直接進下一步,則不易壓縮,因為RGB的明顯易分辨程度是高於YUV的。
公式如下:
為什麼RGB轉明暗度Y的係數不是1/3呢?而是0.299、0.587、0.114?
因為人眼對這三主色光的敏感度不同,所以會有係數不同的情況。
若轉換成YUV後的數值是大於最大色深植,則會將數值設為最大色深值,例如8bits色深值最大255,超過255則會視為255。

2. 分割YUV成多個8×8區塊
這一步的目的是方便下一步的DCT轉換,假如不做切割,則會提高許多運算複雜度。

3. DCT離散餘弦轉換
(來源:
如上圖所示,蒲公英的圖是YUV的Y通道,透過DCT轉換後的頻譜以及數值分布圖(上圖最下),可以看到上圖最下的左,藍色表示數值小,紅色表示數值大,由左至右表示縱向低頻道高頻,由上至下表示橫向低頻道高頻。
上圖最下的右,表示上圖最下的左的所有數值分布狀況。
DCT全名為Discrete Cosine Transform,中文離散餘弦轉換,可以將數值矩陣轉換為頻譜矩陣。
公式有多個版本,以下是第2版一維矩陣的公式:
(來源:
二維矩陣的DCT公式是依序對矩陣做橫向以及縱向DCT,這樣就能獲得二維的DCT頻譜。
在訊號轉頻譜的公式裡有許多種,例如上圖的中間DFT為離散傅立葉轉換,但為什麼JPEG選擇DCT而不是其他的轉換呢?因為DCT可以有效地解決區塊效應問題(8×8區塊邊界間有不平滑的情況),所以才採用DCT。

4. 品質參數降採樣
透過DCT轉換後能看到數值都靠近低頻處(左上),越遠離左上,數值幾乎都是0,為了進一步的壓縮,所以需要JPEG中的品質參數對頻譜的數值進行降採樣,讓大部分的數值都更接近0,品質參數最低是1,當作頻譜數值的除數,若現在有個頻譜數值是18,品質參數是4,運算方式為數值除以品質參數後取商,則18/4 = 4...2,降採樣後的的頻譜數值變為4,若要對JPEG解碼,則將降採樣後的的頻譜數值乘以原先的品質參數即可,例如剛才的降採樣後的的頻譜數值為4,品質參數為4,則還原後的頻譜數值為4*4 = 16,與原先的18有失真現象發生。為了避免失真的情況,可以將品質參數設定為1,這樣這步驟就不會有失真的現象發生。

5. DC DPCM差值壓縮編碼
每個8×8區塊的最低頻數值(左上角)稱作DC值,其他數值稱為AC值,因為每個鄰近的區塊之間都有相關性,所以每個區塊之間的DC值不會相差太大,透過DPCM編碼能有效地進行數值壓縮。
DPCM壓縮方式為只記錄當前區塊DC值減去前個區塊的差值,例如數列1, 3, 5, 4, 2, 2, 2, 2, 2,DPCM數列則為1, 2, 2, -1, -2, 0, 0, 0, 0,因為第一個數值沒有前個參考值,所以給予0作為前一個參考值,DPCM這樣的壓縮編碼能減少紀錄數值所需的位元數。

6. AC Zigzag之字形排列RL編碼
因為經過品質因數降採樣後,大部分的數值都會接近0,且頻率相近的數值間的差異會變小,所以此步驟能有效進行壓縮。
Zigzag之字形,也就是像英文字母Z的方式對二為矩陣數值進行記錄,由左上最低頻處開始記錄,如上圖所示,一路像高頻的方向進行Z字型掃描。
範例如下:
依照Zigzag掃描方式紀錄的數列為15, 0, -2, -1, -1, -1, 0, 0, -1, 0, 0, ..., 0
再透過Run-Length(RL)編碼,就是紀錄數列有幾個0以及下個不是0的數值,RL編碼不會對DC值進行編碼,所以範例的15會跳過記錄方式如下:
一開始的數值為0再來-2,所以共有1個0以及下個數值為2,紀錄為<1, -2>,接著再以-2開始記錄,共有0個0以及下個數值為-1,所以紀錄為<0, -1>,不對值續此步驟,若當前開始的數值到結尾都為0,則紀錄為EOB(End of Block),範例結果為<1, -2>, <0, -1>, <0, -1>, <0, -1>, <2, -1>, <EOB>,原先要記錄63(64-1)個數值,現在只要記錄11個數值。

7. DC Huffman查表
將DC值的DPCM透過DC Huffman查找表編碼成Huffman編碼,Huffman編碼可以參考
https://zh.wikipedia.org/wiki/%E9%9C%8D%E5%A4%AB%E6%9B%BC%E7%BC%96%E7%A0%81
8. AC Huffman查表
將AC值的RL透過ACHuffman查找表編碼成Huffman編碼,Huffman編碼可以參考

JPEG編碼講解完畢。
因為JPEG的編碼的永續開發性較差,所以後續JPEG團隊開發了JPEG2000、JPEG XT等格式,另外影片編碼的H.261~H.265都是以JPEG為基礎加以開發的壓縮格式,了解JPEG編碼後閱讀其他更複雜的壓縮方式是比較容易的。

創作回應

冰凍花枝
比我教授講得還好懂,感謝
2022-11-22 20:49:21

相關創作

更多創作