算術編碼原理

http://blog.csdn.net/adam_tu/article/details/7696455ide

早在1948年,香農就提出將信源符號依其出現的機率降序排序,用符號序列累計機率的二進值做爲對芯源的編碼,並從理論上論證了它的優越性。1960年, Peter Elias發現無需排序,只要編、解碼端使用相同的符號順序便可,提出了算術編碼的概念。Elias沒有公佈他的發現,由於他知道算術編碼在數學上雖然成 立,但不可能在實際中實現。1976年,R. Pasco和J. Rissanen分別用定長的寄存器實現了有限精度的算術編碼。1979年Rissanen和G. G. Langdon一塊兒將算術編碼系統化,並於1981年實現了二進制編碼。1987年Witten等人發表了一個實用的算術編碼程序,即CACM87(後用 於ITU-T的H.263視頻壓縮標準)。同期,IBM公司發表了著名的Q-編碼器(後用於JPEG和JBIG圖像壓縮標準)。今後,算術編碼迅速獲得了 普遍的注意。編碼

算術編碼的基本原理是將編碼的消息表示成實數0和1之間的一個間隔(Interval),消息越長,編碼表示它的間隔就越小,表示這一間隔所需的二進制位就越多。spa

算術編碼用到兩個基本的參數:符號的機率和它的編碼間隔。信源符號的機率決定壓縮編碼的效率,也決定編碼過程當中信源符號的間隔,而這些間隔包含在0到1之間。編碼過程當中的間隔決定了符號壓縮後的輸出。.net

給定事件序列的算術編碼步驟以下:code

(1)編碼器在開始時將「當前間隔」 [ L, H) 設置爲[0,1)。視頻

(2)對每一事件,編碼器按步驟(a)和(b)進行處理htm

(a)編碼器將「當前間隔」分爲子間隔,每個事件一個。blog

(b)一個子間隔的大小與下一個將出現的事件的機率成比例,編碼器選擇子間隔對應於下一個確切發生的事件相對應,並使它成爲新的「當前間隔」。排序

(3)最後輸出的「當前間隔」的下邊界就是該給定事件序列的算術編碼。事件

LowHigh分別表示「當前間隔」的下邊界和上邊界,CodeRange爲編碼間隔的長度,LowRange(symbol)和HighRange(symbol)分別表明爲了事件symbol分配的初始間隔下邊界和上邊界。上述過程的實現可用僞代碼描述以下:

set Low to 0

set High to 1

while there are input symbols do

    take a symbol

    CodeRange = High – Low

    High = Low + CodeRange *HighRange(symbol)

    Low = Low + CodeRange * LowRange(symbol)

end of while

output Low

算術碼解碼過程用僞代碼描述以下:

get encoded number

do

    find symbol whose range straddles the encoded number

    output the symbol

    range = symbo.LowValue – symbol.HighValue

    substracti symbol.LowValue from encoded number

    divide encoded number by range

until no more symbols

算術編碼器的編碼解碼過程可用例子演示和解釋。

例1:假設信源符號爲{A, B, C, D},這些符號的機率分別爲{ 0.1, 0.4, 0.2,0.3 },根據這些機率可把間隔[0, 1]分紅4個子間隔:[0, 0.1], [0.1, 0.5], [0.5, 0.7], [0.7, 1],其中[x,y]表示半開放間隔,即包含x不包含y。上面的信息可綜合在表03-04-1中。

表03-04-1 信源符號,機率和初始編碼間隔

符號

A

B

C

機率

0.1

0.4

0.2

0.3 

初始編碼間隔

[0, 0.1)

[0.1, 0.5)

[0.5, 0.7)

[0.7, 1] 

若是二進制消息序列的輸入爲:C A D A C D B。編碼時首先輸入的符號是C,找到它的編碼範圍是[0.5,0.7]。因爲消息中第二個符號A的編碼範圍是[0, 0.1],所以它的間隔就取[0.5, 0.7]的第一個十分之一做爲新間隔[0.5,0.52]。依此類推,編碼第3個符號D時取新間隔爲[0.514, 0.52],編碼第4個符號A時,取新間隔爲[0.514, 0.5146],…。消息的編碼輸出能夠是最後一個間隔中的任意數。整個編碼過程如圖03-04-1所示。

圖03-04-1 算術編碼過程舉例

這個例子的編碼和譯碼的全過程分別表示在表03-04-2和表03-04-3中。 

表03-04-2 編碼過程

步驟 

輸入符號

編碼間隔 

編碼判決

1

C

[0.5, 0.7]

符號的間隔範圍[0.5, 0.7] 

2

A

[0.5, 0.52]

[0.5, 0.7]間隔的第一個1/10

3

D

[0.514, 0.52]

[0.5, 0.52]間隔的最後一個1/10

4

A

[0.514, 0.5146]

[0.514, 0.52]間隔的第一個1/10

5

C

[0.5143, 0.51442]

[0.514, 0.5146]間隔的第五個1/10開始,二個1/10

6

D

[0.514384, 0.51442]

[0.5143, 0.51442]間隔的最後3個1/10

7

B

[0.5143836, 0.514402]

[0.514384,0.51442]間隔的4個1/10,從第1個1/10開始

8

從[0.5143876, 0.514402]中選擇一個數做爲輸出:0.5143876

表03-04-3 譯碼過程

步驟 

間隔

譯碼符號 

譯碼判決 

1

[0.5, 0.7]

C

0.51439在間隔 [0.5, 0.7)

2

[0.5, 0.52]

A

0.51439在間隔 [0.5, 0.7)的第1個1/10

3

[0.514, 0.52]

D

0.51439在間隔[0.5, 0.52)的第7個1/10

4

[0.514, 0.5146]

A

0.51439在間隔[0.514, 0.52]的第1個1/10

5

[0.5143, 0.51442]

C

0.51439在間隔[0.514, 0.5146]的第5個1/10

6

[0.514384, 0.51442]

D

0.51439在間隔[0.5143, 0.51442]的第7個1/10

7

[0.51439, 0.5143948]

B

0.51439在間隔[0.51439,0.5143948]的第1個1/10

8

譯碼的消息:C A D A C D B

在上面的例子中,咱們假定編碼器和譯碼器都知道消息的長度,所以譯碼器的譯碼過程不會無限制地運行下去。實際上在譯碼器中須要添加一個專門的終止符,當譯碼器看到終止符時就中止譯碼。

在算術編碼中有幾個問題須要注意:

·           因爲實際的計算機的精度不可能無限長,一個明顯的問題是運算中出現溢出,但多數機器都有1六、32或者64位的精度,所以這個問題可以使用比例縮放方法解決。 

·           算術編碼器對整個消息只產生一個碼字,這個碼字是在間隔[0,1]中的一個實數,所以譯碼器在接受到表示這個實數的全部位以前不能進行譯碼。

·           算術編碼也是一種對錯誤很敏感的編碼方法,若是有一位發生錯誤就會致使整個消息譯錯。 

算術編碼能夠是靜態的或者自適應的。在靜態算術編碼中,信源符號的機率是固定的。在自適應算術編碼中,信源符號的機率根據編碼時符號出現的頻繁程度動態地 進行修改,在編碼期間估算信源符號機率的過程叫作建模。須要開發動態算術編碼的緣由是由於事先知道精確的信源機率是很難的,並且是不切實際的。當壓縮消息 時,咱們不能期待一個算術編碼器得到最大的效率,所能作的最有效的方法是在編碼過程當中估算機率。所以動態建模就成爲肯定編碼器壓縮效率的關鍵。

此外,在算術編碼的使用中還存在版權問題。JPEG標準說明的算術編碼的一些變體方案屬於IBM, AT&T和Mitsubishi擁有的專利。要合法地使用JPEG算術編碼必須獲得這些公司的許可。

相關文章
相關標籤/搜索