1. 程式人生 > >數字影象處理第一次作業——JPEG格式與壓縮流程分析

數字影象處理第一次作業——JPEG格式與壓縮流程分析

歡迎閱讀

此篇部落格是由曹老師數字影象處理課程佈置的第一次作業(2018年9月16日) 作業內容: 分析JPEG格式、原理、壓縮流程、下載實現程式碼並調通執行、計算壓縮率。 此篇部落格以分析原理為主,在每個演算法之後會貼出對應的C語言程式碼。 本文程式碼使用的編譯器是Visual Stdio,第一次作業要求深入瞭解壓縮與解壓縮過程,用C/C++實現,不允許使用OpenCv或者matlab直接呼叫庫函式實現,以後將使用OpenCv為主

1.JPEG格式綜述

JPEG是聯合圖象專家組(Joint Picture Expert Group)的英文縮寫,是國際標準化組織(ISO)和CCITT聯合制定的靜態圖象的壓縮編碼標準。JPEG比其它幾種壓縮比要高得多,而圖象質量都差不多,JPEG處理的顏色只有真彩和灰度圖。 JPEG有兩種基本的壓縮演算法、兩種熵編碼方法、四種編碼模式。 壓縮演算法: (1)有損的離散餘弦變換DCT(Discrete Cosine Transform) (2)無損的預測壓縮技術; 熵編碼方法: (1)Huffman編碼; (2)算術編碼; 編碼模式: (1)基於DCT的順序模式:編碼、解碼通過一次掃描完成; (2)基於DCT的漸進模式:編碼、解碼需要多次掃描完成,掃描效果由粗到精,逐級遞增; (3)無損模式:基於DPCM,保證解碼後完全精確恢復到原影象取樣值; (4)層次模式:影象在多個空間解析度中進行編碼,可以根據需要只對低解析度資料做解碼,放棄高解析度資訊; 在實際應用中,JPEG影象編碼演算法使用的大多是離散餘弦變換、Huffman編碼、順序編碼模式。這樣的方式,被人們稱為JPEG的基本系統。基本系統的JPEG壓縮編碼演算法一共分為11個步驟:顏色模式轉換、取樣、分塊、離散餘弦變換(DCT)、Zigzag 掃描排序、量化、DC係數的差分脈衝調製編碼、DC係數的中間格式計算、AC係數的遊程長度編碼、AC係數的中間格式計算、熵編碼。 在這裡插入圖片描述

2.顏色模式轉換

YCrCb即YUV,主要用於優化彩色視訊訊號的傳輸。其中“Y”表示明亮度(Luminance或Luma),也就是灰階值;而“U”和“V” 表示的則是色度(Chrominance或Chroma),作用是描述影像色彩及飽和度,用於指定畫素的顏色。“亮度”是透過RGB輸入訊號來建立的,方法是將RGB訊號的特定部分疊加到一起。“色度”則定義了顏色的兩個方面─色調與飽和度,分別用Cr和Cb來表示。其中,Cr反映了RGB輸入訊號紅色部分與RGB訊號亮度值之間的差異。而Cb反映的是RGB輸入訊號藍色部分與RGB訊號亮度值之間的差異。 RGB->YCrCb的轉換可以用如下公式: Y=

0.299R+0.587G+0.114B Y=0.299R+0.587G+0.114B Cb=0.1687R0.3313G+0.5B+128 Cb = -0.1687R-0.3313G+0.5B+128 Cr=0.5R0.418G0.0813B+128 Cr = 0.5R-0.418G-0.0813B+128

2. 取樣

JPEG圖片中,通常採用兩種取樣方式:YUV411和YUV422,它們所代表的意義是Y,Cb,Cr三個分量的資料取樣比例一般是4:1:1或者4:2:2(4:1:1含義就是:在2x2的單元中,本應分別有4個Y,4個U,4個V值,用12個位元組進行儲存。經過4:1:1取樣處理後,每個單元中的值分別有4個Y、1個U、1個V,只要用6個位元組就可以儲存了)

3.分塊

DCT變換是是對8x8的子塊進行處理的,因此,在進行DCT變換之前必須把源圖象資料進行分塊由左及右,由上到下依次讀取8x8的子塊,存放在長度為64的表中,還必須將每個數值減去128,是因為DCT公式所接受的數字範圍是-128到127之間,之後即可以進行DCT變換。

4. 離散餘弦變換(DCT)

DCT(Discrete Cosine Transform,離散餘弦變換),是位元速率壓縮中常用的一種變換編碼方法。任何連續的實對稱函式的傅立葉變換中只含有餘弦項,因此,餘弦變換同傅立葉變換一樣具有明確的物理意義。DCT是先將整體影象分成NN的畫素塊,然後針對NN的畫素塊逐一進行DCT操作。需要提醒的是,JPEG的編碼過程需要進行正向離散餘弦變換,而解碼過程則需要反向離散餘弦變換 在這裡插入圖片描述 原始的影象訊號(最左邊的波形)經過DCT變換之後變成了8個波,其中第一個波為直流成分,其餘7個為交流成分。 在這裡插入圖片描述

5. Zigzag掃描排序

JPEG 規定按如下圖中的數字順序依次儲存和讀取64 個DCT的係數值,可以使0儘量連在一起,進一步壓縮,減少儲存空間。 在這裡插入圖片描述 在這裡插入圖片描述

6.量化

影象資料轉換為DCT頻率係數之後,還要進行量化階段,才能進入編碼過程。量化階段需要兩個8*8量化矩陣資料,一個是專門處理亮度的頻率係數,另一個則是針對色度的頻率係數,將頻率係數除以量化矩陣的值之後取整,即完成了量化過程。當頻率係數經過量化之後,將頻率係數由浮點數轉變為整數,這才便於執行最後的編碼。不難發現,經過量化階段之後,所有的資料只保留了整數近似值,也就再度損失了一些資料內容。在JPEG演算法中,由於對亮度和色度的精度要求不同,分別對亮度和色度採用不同的量化表。前者細量化,後者粗量化。 下圖給出JPEG的亮度量化表和色度量化表,該量化表是從廣泛的實驗中得出的。當然,也可以自定義量化表。 在這裡插入圖片描述 在這裡插入圖片描述

7.DC係數的差分脈衝調製編碼(DC-DPCM)

88的影象塊經過DCT變換之後得到的DC係數有兩個特點: (1)係數的數值比較大; (2)相鄰的88影象塊的DC係數值變化不大; 根據這兩個特點,DC係數一般採用差分脈衝調製編碼DPCM(Difference Pulse Code Modulation),即:取同一個影象分量中每個DC值與前一個DC值的差值來進行編碼。對差值進行編碼所需要的位數會比對原值進行編碼所需要的位數少了很多。假設某一個88影象塊的DC係數值為15,而上一個88影象塊的DC係數為12,則兩者之間的差值為3。如第一個塊的DC係數為14,第二個塊的DC係數為16,則記錄第一塊的DC係數為14,第二個塊則只記錄差值2,需要2bit,如果不採用DPCM則需要5bit。

8.DC係數的中間格式計算

JPEG中為了更進一步節約空間,並不直接儲存資料的具體數值,而是將資料按照位數分為16組,儲存在表裡面。這也就是所謂的變長整數編碼VLI 在這裡插入圖片描述

9. AC係數的行程長度編碼(RLC)

可以採用行程編碼RLC(Run Length Coding)來更進一步降低資料的傳輸量。利用該編碼方式,可以將一個字串中重複出現的連續字元用兩個位元組來代替,其中,第一個位元組代表重複的次數,第二個位元組代表被重複的字串。 57,45,0,0,0,0,23,0,-30,-8,0,0,1,000… 經過RLC之後,將呈現出以下的形式: (0,57) ; (0,45) ; (4,23) ; (1,-30) ; (0,-8) ; (2,1) ; (0,0)

10.AC係數的中間格式

根據前面提到的VLI表格,對於前面的字串: (0,57) ; (0,45) ; (4,23) ; (1,-30) ; (0,-8) ; (2,1) ; (0,0)只處理每對數右邊的那個資料,對其進行VLI編碼: 查詢上面的VLI編碼表格,可以發現,57在第6組當中,因此,可以將其寫成(0,6),57的形式,該形式,稱之為AC係數的中間格式。同樣的(0,45)的中間格式為:(0,6),45; (1,-30)的中間格式為:(1,5),-30;

11.熵編碼

Huffman編碼:對出現概率大的字元分配字元長度較短的二進位制編碼,對出現概率小的字元分配字元長度較長的二進位制編碼,從而使得字元的平均編碼長度最短。Huffman編碼時DC係數與AC係數分別採用不同的Huffman編碼表,對於亮度和色度也採用不同的Huffman編碼表。因此,需要4張Huffman編碼表才能完成熵編碼的工作。

12.壓縮和解壓縮的程式碼

壓縮和解壓縮的完整程式碼實在是太長了,檔案也太多了,就不放了(捂臉)