对普通文件 霍夫曼编解码 matlab,JPEG编解码过程详解(二)
2.4?量化(quantization)
量化過程是一個將信號的幅度離散化的過程,離散信號經過量化后變為數字信號。
由于HVS對低頻信號更為敏感,所以對信號的低頻部分采用相對短的量化步長,對信號的高頻部分采用相對長的量化步長。這樣可以在一定程度上,得到相對清晰的圖像和更高的壓縮率。
2.5?Z字形編碼(zigzag scan)
按Z字形把量化后的數據讀出,例:
2.6?使用行程長度編碼(RLE)對交流系數(AC)進行編碼
所謂游程長度編碼是指一個碼可以同時表示碼的值和前面有幾個零。這樣就發揮了Z字型讀出的優點,因為Z字型讀出,出現連零的機會比較多,特別到最后,如果都是零,在讀到最后一個數后,只要給出“塊結束”(EOB)碼,就可以結束輸出,因此節省了很多碼率。
例:圖中按Z字形抽取和游程編碼得到碼值為
(0,1,0)(1,2,0)(0,5,0)(0,4,0)(4,8,1)EOB
這樣一個4*4的矩陣用很少的數值就能表示!
2.7?熵編碼
常用的熵編碼有變長編碼,即哈夫曼編碼。
哈夫曼的編碼方法:對出現概率大的符號分配短字長的二進制碼,對出現概率小的符號分配長字長的二進制碼,得到符號平均碼長最短的碼。
哈夫曼編碼的步驟:(1). 把信源符號按概率大小順序排列, 并設法按逆次序分配碼字的長度。 (2). 在分配碼字長度時,首先將出現概率最小的兩個符號的概率相加合成一個概率 (3). 把這個合成概率看成是一個新組合符號地概率,重復上述做法直到最后只剩下兩個符號概率為止。 (4). 完成以上概率順序排列后,再反過來逐步向前進行編碼,每一次有二個分支各賦予一個二進制碼,可以對概率大的賦為零,概率小的賦為1。
關于AC/DC系數的編碼
1.AC系數的Huffman編碼
經過Z掃描和游程編碼后的非零AC系數被表述為符號A和符號B。符號A由(Runlength,Size)構成,符號B(Amplitude)。
Runlength為非零AC系數前連續為0的AC系數;
Size則是表示編碼Amplitude所需要的比特位數;
Amplitude為AC系數的幅值。
實際操作時,JPEG用一個8位的值RS來表示符號A,RS=RRRRSSSS,對于一個非零的AC系數,高四位用來表示Runlength,低四位用來表示Size。(00000000)用來表示EOB。
對符號B進行變字長整數(VLI)編碼,將符號B的VLI碼放在A后從而形成對A,B編碼的最終結果。
2.DC系數的Huffman編碼
對于DC系數,與非零的AC系數類似,它將相鄰兩塊DC系數的差值(DIFF)描述如下的符號對:符號A為(Size),符號B為(Amplitude)。
Size表示為編碼Amplitude所需要的位數;
Amplitude表示DC系數的幅值。
在JPEG標準中,對符號A根據相應的Huffman表進行變字長編碼,對符號B進行變字長整數編碼,而后將符號B 的VLI碼放在符號A的Huffman碼后,從而完成了對DIFF的編碼。
在JPEG標準中沒有定義缺省的Huffman表,用戶可以根據實際應用自由選擇,可以預先定義一個通用的Huffman表,也可以針對一幅特定的圖像,在壓縮編碼前通過搜集其統計特性來計算Huffman表。
三,JPEG解碼的主要過程。
3.1?讀入文件的相關信息
按照JPEG文件數據存儲方式,把要解碼的文件的相關信息一一讀出,為接下來的解碼工作做好準備。參考方法是,設計一系列的結構體對應各個標記,并存儲標記內表示的信息。其中圖像長寬、多個量化表和哈夫曼表、水平/垂直采樣因子等多項信息比較重要。以下給出讀取過程中的幾個問題。
1. 讀取文件的大體結構
JFIF格式的JPEG文件(*.jpg)的一般順序為:
SOI(0xFFD8),APP0(0xFFE0),[APPn(0xFFEn)]可選,
DQT(0xFFDB),SOF0(0xFFC0),DHT(0xFFC4),SOS(0xFFDA),
壓縮數據,EOI(0xFFD9)。
2. 讀取哈夫曼表數據;
3. 建立哈夫曼樹。
在準備好所有的圖片信息后,就可以對圖片數據進行解碼了。
關于AC,DC系數的解碼
1. AC系數的解碼
通過查詢Huffman數據解出RS,從中的到Runlength和Size的值。因為符號B是通過VLI表來編碼的,所以通過查詢Size的值可以得到Amplitude。這樣就可以解出符號A和符號B的值了。
2. DC系數的解碼
同理,先查詢Huffman表解出Size的,通過Size解出DIFF,將其與上一個8*8塊的DC系數數值相加,最終得到該塊的DC系數。
3.2 MCU中顏色分量(Y,U,V)的解碼
圖像數據流是有MCU組成,而MCU是用數據單元和顏色分量構成。圖像數據流是以位(bit)為單位存儲信息的。并且內部的數據都是在編碼時通過正向離散余弦變換(FDCT)進行時空域向頻率域變換而得到的結果,所以對于每個顏色分量單元都應該由兩部分組成:1個直流分量和63個交流分量。
顏色分量單元內部綜合運用了RLE行程編碼和哈夫曼編碼來壓縮數據。每個像素的數據流由兩部分構成:編碼和數值,并且兩者基本以互相隔開方式出現(除非該編碼的權值為零)。解碼的過程其實就是哈夫曼樹的查找過程。
3.3 直流系數的差分編碼
把所有的顏色分量單元按顏色分量(Y、Cr、Cb)分類。每一種顏色分量內,相鄰的兩個顏色分量單元的直流變量是以差分來編碼的。也就是說,通過之前解碼出來的直流變量數值只是當前顏色分量單元的實際直流變量減去前一個顏色分量單元的實際直流變量。也就是說,當前直流變量要通過前一個顏色分量單元的實際(非解碼)直流分量來校正:
DCn=DCn-1+Diff
其中Diff為差分校正變量,也就是直接解碼出來的直流系數。但如果當前顏色分量單元是第一個單元,則解碼出來的直流數值就是真正的直流變量。
3個顏色分量的直流變量是分開進行差分編碼的。也就是說,為1張圖片解碼時應設置3個獨立的直流校正變量。
3.4 反量化
反量化的過程比較簡單。只需要對8*8的顏色分量單元的64個值逐一乘以對應的量化表內位置相同的值則可。圖像內全部的顏色分量單元都要進行反量化。
3.5 反Zig-zag編碼
3.6 反離散余弦變換
之前提到,文件中的數據是在編碼時通過正向離散余弦變換(FDCT)進行時空域向頻率域變換而得到的結果,所以現在解碼就必須將其反向離散余弦變換(IDCT),就是把顏色分量單元矩陣中的頻率域數值向時空域轉換。并且,原來的頻率域的矩陣大小為8*8,則經過反向離散余弦變換后,時空域的矩陣仍然是8*8。
3.7 YCrCb向RGB轉換
要在屏幕上顯示圖像,就必須以RGB模式表示圖像的顏色。所以,解碼時需要把YCrCb模式向RGB模式轉換。
另外,由于離散余弦變化要求定義域的對稱,所以在編碼時把RGB的數值范圍從[0,255]統一減去128偏移成[-128,127]。因此解碼時必須為每個分量加上128。具體公式如下:
R=?Y?+1.402*Cb?+128;
G=Y-0.34414*Cr?-0.71414*Cb?+128;
B=?Y?+1.772*Cb?+128;
還有一個問題,通過變換得出的R、G、B值可能超出了其定義域,所以要作出檢查。如果大于255,則截斷為255;如果小于0,則截斷為0。
至此,每個MCU的解碼已經完成。
原文作者:quennel
總結
以上是生活随笔為你收集整理的对普通文件 霍夫曼编解码 matlab,JPEG编解码过程详解(二)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Mongodb模式设计
- 下一篇: 【图像压缩】基于余弦变换及霍夫曼编码实现