JPEG

引用:http://www.cnblogs.com/laughterwym/archive/2006/06/23/433793.html

一、JPEG算法概要
  JPEG(Joint Photographic Experts Group)是一個由ISO和IEC兩個組織機構聯合組成的一個專家組,負責制定靜態的數字圖像數據壓縮編碼標準,這個專家組開發的算法稱爲JPEG算法,並且成爲國際上通用的標準,因此又稱爲JPEG標準。JPEG是一個適用範圍很廣的靜態圖像數據壓縮標準,既可用於灰度圖像又可用於彩色圖像。
  JPEG專家組開發了兩種基本的壓縮算法,一種是採用以離散餘弦變換(Discrete Cosine Transform,DCT)爲基礎的有損壓縮算法,另一種是採用以預測技術爲基礎的無損壓縮算法。使用有損壓縮算法時,在壓縮比爲25:1的情況下,壓縮後還原得到的圖像與原始圖像相比較,非圖像專家難於找出它們之間的區別,因此得到了廣泛的應用。例如,在VCD和DVD-Video電視圖像壓縮技術中,就使用JPEG的有損壓縮算法來取消空間方向上的冗餘數據。爲了在保證圖像質量的前提下進一步提高壓縮比,近年來JPEG專家組正在制定JPEG2000標準,這個標準中將採用小波變換(Wavelet)算法。
  JPEG壓縮是有損壓縮,它利用了人的視角系統的特性,使用量化和無損壓縮編碼相結合來去掉視角的冗餘信息和數據本身的冗餘信息。JPEG算法框圖如圖:

壓縮編碼大致分成三個步驟:
1、使用正向離散餘弦變換(Forward Discrete Cosine Transform,FDCT)把空間域表示的圖變換成頻率域表示的圖。
2、使用加權函數對DCT係數進行量化,這個加權函數對於人的視覺系統是最佳的。
3、使用霍夫曼可變字長編碼器對量化係數進行編碼。

譯碼或者叫做解壓縮的過程與壓縮編碼過程正好相反。

  JPEG算法與彩色空間無關,因此“RGB到YUV變換”和“YUV到RGB變換”不包含在JPEG算法中。JPEG算法處理的彩色圖像是單獨的彩色分量圖像,因此它可以壓縮來自不同彩色空間的數據,如RGB, YCbCr和CMYK。

二、JPEG算法的主要計算步驟
  JPEG壓縮編碼算法的主要計算步驟如下:
    (1)正向離散餘弦變換(FDCT)。
    (2)量化(Quantization)。
    (3)Z字形編碼(Zigzag Scan)。
    (4)使用差分脈衝編碼調製(Differential Pulse Code Modulation,DPCM)對直流係數(DC)進行編碼。
    (5)使用行程長度編碼(Run-Length Encoding,RLE)對交流係數(AC)進行編碼。
    (6)熵編碼(Entropy Eoding)。

1、正向離散餘弦變換
  下面對正向離散餘弦變換(FDCT)變換作幾點說明。
  (1)對每個單獨的彩色圖像分量,把整個分量圖像分成若干個8×8的圖像塊,如圖所示,並作爲兩維離散餘弦變換DCT的輸入。通過DCT變換,把能量集中在少數幾個係數上。
 

  (2)DCT變換使用下式計算:

  它的逆變換使用下式計算:

上面兩式中,
C(u),C(v) = (2)-1/2,當u, v = 0;
C(u),C(v) = 1,其他。
f(i, j)經DCT變換之後,F(0,0)是直流係數,其他爲交流係數。

  (3)在計算兩維的DCT變換時,可使用下面的計算式把兩維的DCT變換變成一維的DCT變換:




2、量化
  量化是對經過FDCT變換後的頻率係數進行量化。量化的目的是減小非“0”係數的幅度以及增加“0”值係數的數目。量化是圖像質量下降的最主要原因。
  對於有損壓縮算法,JPEG算法使用如下圖所示的均勻量化器進行量化,量化步距是按照係數所在的位置和每種顏色分量的色調值來確定。因爲人眼對亮度信號比對色差信號更敏感,因此使用了兩種量化表:亮度量化值和色差量化值。此外,由於人眼對低頻分量的圖像比對高頻分量的圖像更敏感,因此圖中的左上角的量化步距要比右下角的量化步距小。下面2個表中的數值對CCIR 601標準電視圖像已經是最佳的。如果不使用這兩種表,你也可以把自己的量化表替換它們。


亮度量化值表和色度量化值表


3、Z字形編排
  量化後的係數要重新編排,目的是爲了增加連續的“0”係數的個數,就是“0”的遊程長度,方法是按照Z字形的式樣編排,如下圖所示。這樣就把一個8×8的矩陣變成一個1×64的矢量,頻率較低的係數放在矢量的頂部。


量化DCT係數序號

0

1

5

6

14

15

27

25

2

4

7

13

16

26

29

42

3

8

12

17

25

30

41

43

9

11

18

24

31

40

44

53

10

19

23

32

39

45

52

54

20

22

33

38

46

51

55

60

21

34

37

47

50

56

59

61

35

36

48

49

57

58

62

63



4、直流係數的編碼
  8×8圖像塊經過DCT變換之後得到的DC直流係數有兩個特點,一是係數的數值比較大,二是相鄰8×8圖像塊的DC係數值變化不大。根據這個特點,JPEG算法使用了差分脈衝調製編碼(DPCM)技術,對相鄰圖像塊之間量化DC係數的差值(Delta)進行編碼。
Delta=DC(0,0)k-DC(0,0)k-1

5、 交流係數的編碼
  量化AC係數的特點是1×64矢量中包含有許多“0”係數,並且許多“0”是連續的,因此使用非常簡單和直觀的遊程長度編碼(RLE)對它們進行編碼。
  JPEG使用了1個字節的高4位來表示連續“0”的個數,而使用它的低4位來表示編碼下一個非“0”係數所需要的位數,跟在它後面的是量化AC係數的數值。

6、熵編碼
  使用熵編碼還可以對DPCM編碼後的直流DC係數和RLE編碼後的交流AC係數作進一步的壓縮。
  在JPEG有損壓縮算法中,使用霍夫曼編碼器來減少熵。使用霍夫曼編碼器的理由是可以使用很簡單的查表(Lookup Table)方法進行編碼。壓縮數據符號時,霍夫曼編碼器對出現頻度比較高的符號分配比較短的代碼,而對出現頻度較低的符號分配比較長的代碼。這種可變長度的霍夫曼碼錶可以事先進行定義。

7、組成位數據流
  JPEG編碼的最後一個步驟是把各種標記代碼和編碼後的圖像數據組成一幀一幀的數據,這樣做的目的是爲了便於傳輸、存儲和譯碼器進行譯碼,這樣的組織的數據通常稱爲JPEG位數據流(JPEG bitstream)。 
 

JPG 文件(Byte 級)裏怎樣組織圖片信息
-----------------------------------
注意 JPEG/JFIF 文件格式使用 Motorola 格式, 而不是 Intel 格式,
就是說, 如果是一個字的話, 高字節在前, 低字節在後.

JPG 文件是由一個個段 (segments) 構成的. 每個段長度 <=65535. 每個段從
一個標記字開始. 標記字都是 0xff 打頭的, 以非 0 字節和 0xFF 結束. 例如
’FFDA’ , ’FFC4’, ’FFC0’. 每個標記有它特定意義, 這是由第2字節指明的.
例如, SOS (StartOf Scan = ’FFDA’) 指明瞭你應該開始解碼. 另一個標記
DQT (Define QuantizationTable = 0xFFDB) 就是說它後面有 64 字節的
quantization 表

在處理 JPG 文件時, 如果你碰到一個 0xFF, 而它後面的字節不是 0, 並且這個
字節沒有意義. 那麼你遇到的 0xFF 字節必須被忽略. (一些 JPG 裏, 常用用
0xFF 做某些填充用途) 如果你在做 huffman 編碼時碰巧產生了一個 0xFF, 那
麼就用 0xFF 0x00 代替. 就是說在 jpeg 圖形解碼時碰到 FF00 就把它當作 FF 處理.

另外在 huffman 編碼區域結束時, 碰到幾個 bit 沒有用的時候, 應該用 1 去填充.
然後後面跟 FF.

下面是幾個重要的標記
--------------------

SOI = Start Of Image = ’FFD8’
這個標記只在文件開始出現一次
EOI = End Of Image = ’FFD9’
JPG 文件都以 FFD9 結束

RSTi = FFDi ( i = 0..7) [ RST0 = FFD0, RST7=FFD7]
= 復位標記
通常穿插在數據流裏, 我想是擔心 JPG 解碼出問題吧(應該配合 DRI 使用).
不過很多 JPG 都不使用它

(SOS --- RST0 --- RST1 -- RST2 --...
...-- RST6 --- RST7 -- RST0 --...)

----
標記
----
下面是必須處理的標記

SOF0 = Start Of Frame 0 = FFC0
SOS = Start Of Scan = FFDA
APP0 = it’s the marker used to identify a JPG file which uses the JFIF
specification = FFE0
COM = Comment = FFFE
DNL = Define Number of Lines = FFDC
DRI = Define Restart Interval = FFDD
DQT = Define Quantization Table = FFDB
DHT = Define Huffman Table = FFC4

 

一個 (Hmax*8,Vmax*8) 的塊被稱作 MCU (Minimun Coded Unix) 前面例子
中一個 MCU = YDU,YDU,YDU,YDU,CbDU,CrDU

如果 HY =1, VY=1
HCb=1, VCb=1
HCr=1, VCr=1
這樣 (Hmax=1,Vmax=1), MCU 只有 8x8 大, MCU = YDU,CbDU,CrDU

對於灰度 JPG, MCU 只有一個 DU (MCU = YDU)

JPG 文件裏, 圖象的每個組成部分的採樣係數定義在 SOF0 (FFC0) 標記後

簡單說一下 JPG 文件的解碼
-------------------------
解碼程序先從 JPG 文件中讀出採樣係數, 這樣就知道了 MCU 的大小, 算出整
個圖象有幾個 MCU. 解碼程序再循環逐個對 MCU 解碼, 一直到檢查到 EOI 標
記. 對於每個MCU, 按正規的次序解出每個 DU, 然後組合, 轉換成 (R,G,B) 就 OK 了

附:JPEG 文件格式
~~~~~~~~~~~~~~~~

- 文件頭 (2 bytes): $ff, $d8 (SOI) (JPEG 文件標識)
- 任意數量的段 , 見後面
- 文件結束 (2 bytes): $ff, $d9 (EOI)

段的格式:
~~~~~~~~~

- header (4 bytes):
$ff 段標識
n 段的類型 (1 byte)
sh, sl 該段長度, 包括這兩個字節, 但是不包括前面的 $ff 和 n.
注意: 長度不是 intel 次序, 而是 Motorola 的, 高字節在前,
低字節在後!
- 該段的內容, 最多 65533 字節

 

 

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