Kodowanie informacji
Transkrypt
Kodowanie informacji
Studia Wieczorowe Wrocław, 27.03.2007 Kodowanie informacji Wykład 5 Kodowanie predykcyjne Idea: − − przewidujemy następny element ciągu i kodujemy różnicę między wartością przewidywaną i rzeczywistą, w oparciu o kontekst (wybrane symbole spośród wcześniej zakodowanych, w sąsiedztwie kodowanego), określamy rozkład prawdopodobieństwa stosowany przy kodowaniu bieżącego symbolu, zazwyczaj przy użyciu algorytmów dla ciągów niezależnych wartości. Przykład: Słowo prawdopodobieństwo, zakodowana część to prawdopo, rozkład dla następnej litery w kontekście prawdopo NA PEWNO preferuje d. WADA: np. kontekstów 8-literowych jest 268 czyli kolosalnie dużo. Predykcja z częściowym dopasowaniem (ppm=prediction with partial matching) Autorzy: Cleary, Witten Rok: 1984 Idea: − stosujemy kodowanie arytmetyczne (właściwie implementację całkowitoliczbową) − rozkłady prawdopodobieństwa zależne od kontekstu kodowanej litery, − rozkłady ustalane dynamicznie, w oparciu o przeczytane dane! − znamy rozkłady TYLKO dla kontekstów, które już wystąpiły, − rozważamy konteksty o różnych długościach, ale nie większe od ustalonego maksimum. Pojęcia: Kontekst: Dany tekst prawdopod Dla ostatniej litery: Rząd kontekstu 0 1 2 3 Kontekst Pusty o po opo Konteksty nietypowe: − kontekst rzędu 0 – liczba wystąpień litery, − kontekst rzędu –1 – oznacza rozkład jednostajny na wszystkich symbolach alfabetu (rozważany, gdy litera nie wystąpiła w tekście w ogóle). Licznik kontekstu dla litery t i kontekstu k: określa ile razy t wystąpiła (w dotychczas przeczytanej części tekstu) w kontekście k. W przypadku kontekstu k rzędu 0 licznik określa liczbę wystąpień litery t w tekście. Symbol Escape – „wirtualny” symbol w każdym kontekście, który kodujemy gdy symbol kodowany NIE wystąpił jeszcze w danym kontekście. UWAGA: przyjmujemy, że w każdym kontekście symbol Escape wystąpił jeden raz. Tablica częstości dla kontekstu k: zawiera liczniku kontekstu k dla wszystkich liter t, które wystąpiły w kontekście k, i dla symbolu Escape: Tablica kontekstów długości j: zawiera wszystkie konteksty o długości j, które wystąpiły w tekście, wraz z ich licznikami kontekstu. ALGORYTM KODOWANIA: Dane: Kodowany tekst x=x1..xn Maksymalna długość kontekstu m. Algorytm (uwaga – w praktyce używana całkowitoliczbowa wersja kodowania arytmetycznego): lw := 0; pr := 1; Dla każdego j=0,1,..,m Tablica kontekstów długości j - PUSTA Dla i = 1,2,...,n (kodowanie xi): Niech p ≤ m to maksymalna wartość taka, że tablica kontekstu dla xi-p..xi-1 jest niepusta znaleziony = false Dla j = p, p-1,...2,1,0: − y = xi-j..xi-1 − zmodyfikuj licznik kontekstu y dla litery xi; − Jeśli (znaleziony=false oraz xi wystąpiło wcześniej w kontekście y): o wybierz podprzedział odpowiadający xi, zmodyfikuj lw, pr; o znaleziony := true − Jeśli (znaleziony=true oraz xi NIE wystąpiło wcześniej w kontekście y): o wybierz podprzedział odpowiadający symbolowi Escape w kontekście y, zmodyfikuj lw, pr. Zakodowana postać tekstu to wartość znacznika (zaokrąglana tak jak w „klasycznym” kodowaniu arytmetycznym). DEKODOWANIE: analogicznie do dekodowania w przypadku kodowania arytmetycznego, z tym, że po każdym odkodowanym symbolu modyfikowane są tablice kontekstów, tak samo jak w procesie kodowania. Przykład – sposób ustalania podprzedziałów: Maksymalna długość kontekstu m=2 (w praktyce stosuje się co najmniej 5): Kodujemy fragment est, dokładniej literę t. Zakładamy, że tablica kontekstów długości 2 zawiera następującą tablicę częstości dla kontekstu es: Kontekst: es Litera Licznik s 3 y 2 Escape 1 Widzimy więc, że: − t nie wystąpiło w kontekście es, kodujemy symbol Escape − kodowanie Escape: prawdopodobieństwo równe 1/(3+2+1)=1/6, w podziale przedziału „oryginalnego” zajmuje „ostatnią” część [5/6; 1), modyfikujemy przedział. Dodajemy do tablicy kontekstu es wystąpienie t: Kontekst: es Litera Licznik s 3 t 1 y 2 Escape 1 Przechodzimy do kontekstów rzędu 1, dla s tablica zawiera: Kontekst: s Litera Licznik y 5 s 4 u 1 t 2 Escape 1 Zatem: − kodujemy t: jego prawdopodobieństwo to 2/(5+4+1+2+1)=2/13, odpowiada mu przedział [10/13,12/13), wg tych proporcji dzielimy aktualny podprzedział; − zwiększamy licznik t o jeden. Kontekst: s Litera Licznik y 5 s 4 u 1 t 3 Escape 1 modyfikujemy też tabelę kontekstu pustego! UWAGI: − rozważane różne modyfikacje inaczej traktujące symbol Escape (ppma, ppmb, ppmc). − wzrost długości kontekstu tylko do pewnego momentu zwiększa kompresję (dla długich − kontekstów będziemy być może musieli wielokrotnie kodować symbol Escape); zasada wyłączania: jeśli odrzuciliśmy dłuższy kontekst, to w krótszym nie uwzględniamy liter, które pojawiły się w dłuższym (PRZYKŁAD – może być powyższy), co zwiększa prawdopodobieństwo symbolu kodowanego. Algorytm Burrowsa-Wheelera (BWT) Autor: Burrows (1994) w oparciu o transformatę Wheelera (1983). Cechy: − nie jest możliwe kodowanie on-line − algorytm dekompresji mało oczywisty, ale wymaga mniej obliczeń niż kompresja. KODOWANIE: Dane: Tekst x=x1..xn o długości n. Wynik: ciąg y1..yn oraz liczba j z przedziału [1,n] Algorytm: 1. Niech X1, X2,...,Xn to wszystkie przesunięcia cykliczne x 2. Niech Y1, Y2, ...,Yn oznacza uporządkowany leksykograficznie zbiór {X1,..,Xn} 3. yi to ostatni znak napisu Yi 4. j to pozycja ciągu x w ciągu Y. Przykład. Dane (przyjmujemy, że kolejność liter alfabetu jest następująca ; < O < T < U): x=OTO;TU;TO X1 X2 X3 X4 X5 X6 X7 X8 X9 OTO;TU;TO TO;TU;TOO O;TU;TOOT ;TU;TOOTO TU;TOOTO; U;TOOTO;T ;TOOTO;TU TOOTO;TU; OOTO;TU;T Zakodowana postać tekstu: [UOTTOO;;T Y1 Y2 Y3 Y4 Y5 Y6 Y7 Y8 Y9 ;TOOTO;TU ;TU;TOOTO O;TU;TOOT OOTO;TU;T OTO;TU;TO TO;TU;TOO TOOTO;TU; TU;TOOTO; U;TOOTO;T 5]. DEKODOWANIE: Dane: [y1..yn j] Wynik: odkodowany ciąg D[1]..D[n] 1. Posortuj y1..yn : niech z1..zn to posortowany ciąg y1..yn 2. Wartości 1..n oznacz jako WOLNE 3. Dla i = 1..n a. wyznacz minimalne k takie, że yi = zk i k WOLNE b. oznacz k jako zajęte c. T[i]:=k 4. D[n]:= yj 5. k := j 6. Dla i=1..n-1 a. k := T[k] b. D[n-i] := yk PRZYKŁAD: Dane: [ UOTTOO;;T 5 ] Ciąg y1..yn z1..zn T 1 U ; 9 2 O ; 3 3 T O 6 4 T O 7 5 O O 4 6 O T 5 7 ; T 1 8 ; T 2 9 T U 8 D O T O ; T U ; T O k = 5 oryginalny posortowany 4 7 1 9 8 2 3 PYTANIA: 1. Jaki cel kodowania skoro brak kompresji: Uzyskujemy długie ciągi powtórzeń tego samego symbolu – a następnie wykorzystujemy metody kompresji bazujące na takiej zależności. 2. Skąd biorą się te ciągi powtórzeń? Przykład: jaki symbol występować będzie (często) na ostatniej pozycji cyklicznych przesunięć zaczynających się od est? Odpowiedź na to pytanie wyjaśnia, że w postaci zakodowanej będą występować ciągi powtórzeń tego samego znaku! 3. Czy ten algorytm jest poprawny – czy dekompresja zawsze prowadzi do odtworzenia oryginalnego tekstu? Uzyskanie kompresji – kodowanie ciągu wynikowego metodą mtf (move to front). Dane: ciąg x = x1..xn Algorytm: 1. Przyporządkowanie kolejnych liczb naturalnych symbolom występującym w danych (od zera). 2. Dla i=1,..,n a. zakoduj xi za pomocą liczby odpowiadającej jego numerowi (i prześlij kod) b. przenieś xi na pozycję 0 (a symbole występujące przed nim o jedną pozycję niżej) Efekt: ciągi powtórzeń tego samego symbolu zostają zamienione na ciągi zer; dla wynikowego ciągu stosujemy metodę dla ciągów niezależnych wartości (np. kodowanie arytmetyczne). POPRAWNOŚĆ ALGORYTMU Burrowsa-Wheelera (dekodowanie): Obserwacje: 1. Traktujemy ciąg do zakodowania jako słowo cykliczne, w szczególności przyjmujemy, że ostatni symbol poprzedza pierwszy. 2. Wtedy relacja poprzedzania jest taka sama na wszystkich ciągach będących cyklicznymi przesunięciami ciągu oryginalnego. 3. Zauważmy, że o ostatni symbol ciągu kodowanego (czyli xn) znamy z jego postaci zakodowanej y (jest na pozycji j), o a pierwszy symbol ciągu x to j-ty symbol po posortowaniu y, czyli j-ty symbol ciągu z (tak samo jest dla innych ciągów!). 4. Gdybyśmy dla j-tego wiersza wśród wierszy posortowanych potrafili znaleźć POZYCJĘ j’, jego cyklicznego przesunięcia o jeden w prawo to znalibyśmy przedostatni symbol tekstu, ponieważ - ostatni symbol stałby się pierwszym, przedostatni będzie ostatnim symbolem w j’, który możemy prosto wyznaczyć z ciągu y (jest y[j’]). 5. Pozycje cyklicznych przesunięć wierszy w prawo wyznacza właśnie tablica T. Dowód: Niech y – ciąg ostatnich pozycji w tablicy posortowanej, z – ciąg pierwszych pozycji (czyli posortowany) Zauważmy, że cykliczne przesunięcie w prawo o jeden wiersza j - zaczyna się od ostatniego znaku wiersza j (powiedzmy a), - zatem jest na jednej z pozycji, na której w słowie z występuje litera a. Skoro jednak ciągi są posortowane, to dwa ciągi zaczynające się od a posortowane są względem pozostałych pozycji – wobec tego przesunięcie w prawo pierwszego ciągu kończącego się na a jest na pozycji pierwszego a w słowie z, drugiego na pozycji drugiego a, itd. 6. W oparciu o powyższe obserwacje – najpierw wyznaczamy ostatni symbol ciągu dekodowanego równy yj, jest on pierwszym symbolem w ciągu na pozycji T[j], więc poprzedza go ostatni w T[j] symbol y[T[j]], ten z kolei jest pierwszy w T[T[j]] więc poprzedza go y[T[T[j]]] itd. Przykład: [UOTTOO;;T 5] y= UOTTOO;;T z=;;OOOTTTU PRZESUNIECIA: Y1 Y2 Y3 Y4 Y5 Y6 Y7 Y8 Y9 ;TOOTO;TU ;TU;TOOTO O;TU;TOOT OOTO;TU;T OTO;TU;TO TO;TU;TOO TOOTO;TU; TU;TOOTO; U;TOOTO;T Bezstratny JPEG (JPEG-LS) JPEG=Joint Photographic Experts Group JPEG-LS: standard starszy – statyczny i wieloprzebiegowy: KROK 1. wybieramy jeden z ośmiu trybów predykcji (np. najlepszy po sprawdzeniu wszystkich): I’(i,j)= 1 0 2 I(i-1,j) 3 I(i,j-1) 4 I(i-1,j-1) 5 I(i,j-1) + I(i-1, j) – I(i-1, j-1) 6 I(i,j-1) + (I(i-1,j)-I(i-1, j-1))/2 7 I(i-1,j) + (I(i,j-1) – I(i-1, j-1))/2 8 (I(i,j-1) + I(i-1,j))/2 KROK 2. Dla kolejnych pikseli kodujemy różnice między wartością predykcji i faktyczną wartością piksela: I’(i,j)-I(i,j). KROK 3. Ciąg utworzony w kroku 2 kodujemy algorytmem kodowania ciągów niezależnych wartości (np. kodowanie arytmetyczne). JPEG-LS: standard nowszy – podejście dynamiczne, jednoprzebiegowe (podobne do CALIC) WW NN NNE NW N NE W X Krok 1: Dla piksela X wyznaczamy wartość przewidywaną wg algorytmu: 1. Jeśli NW ≥ max(W, N) to X’ = max(W,N), w przeciwnym razie: 2. Jeśli NW ≤ min(W, N) to X’ = min(W,N) 3. Jeśli nie zachodzi 1. ani 2. : X’ = W+N-NW Krok 2: X’=X’+S, gdzie S – średnia wartość błędu predykcji w aktualnym kontekście Krok 3: Kodujemy różnicę między X’ a rzeczywistą wartość piksela X. Używamy kodu Golomba (adaptacyjnego!) najlepszego dla rozkładu geometrycznego – zakładamy że przy liniowym wzroście błędu predykcji prawdopodobieństwo maleje wykładniczo. Konteksty: Niech: D1 = NE-N D2 = N-NW D3 = NW-W W oparciu o parametry T1, T2, T3 (które można dowolnie modyfikować – może to robić nawet „użytkownik”) określamy wektor kontekstu Q=(Q1, Q2, Q3), gdzie − Qi ∈ {-4, -3, -2, -1, 0, 1, 2, 3, 4} − jeśli Di=0 to Qi=0 − jeśli Di>0 to Qi=c takie, że Tc-1 ≤ Di ≤ Tc − jeśli Di<0 to Qi=-c takie, że –Tc ≤ Di ≤ -Tc-1. Liczba kontekstów = 93=729 Redukcja liczby kontekstów: kontekst (Q1, Q2, Q3) z Q1<0 zastępujemy przez (-Q1, -Q2, -Q3) i ustawiamy SIGN:= -1 (w dalszym etapie do pierwotnej wartości przewidywanej dodajemy błąd predykcji mnożony przez SIGN) Odwzorowanie (Q1, Q2, Q3) → {1, 2, ..., 365} Wiele poziomów rozdzielczości Metoda HINT: ∆ • X • ∆ • X • ∆ • ∗ • ∗ • ∗ • ∗ X • ° • X • ° • X • ∗ • ∗ • ∗ • ∗ • ∆ • X • ∆ • X • ∆ • ∗ • ∗ • ∗ • ∗ • X • ° • X • ° • X • ∗ • ∗ • ∗ • ∗ • ∆ • X • ∆ • X • ∆ • Kolejność kodowania: - kodujemy „obraz” złożony z pikseli ∆ - kodujemy „obraz” złożony z pikseli °, korzystając z wartości, stosując predykcję i kodując różnice między wartością predykcji i rzeczywistą - kodujemy kolejno: X, ∗ i • Progresywna transmisja obrazu z kompresją – schemat hierarchiczny Idea: najpierw przesyłamy wersje obrazu o mniejszej rozdzielczości, następnie o większej; wersje o większej rozdzielczości uzyskujemy z tych o mniejszej rozdzielczości. Metoda „oszczędnego” przejścia z obrazu o rozdzielczości mxm do rozdzielczości 2m x 2m: - na poziomie m x m jeden piksel reprezentuje średnią arytmetyczną czterech pikseli, do odbiorcy przesyłamy sumę wartości tych 4 pikseli; - przy przejściu do rozdzielczości 2mx2m przesyłamy wartości 3 pikseli, czwarty wyznaczamy jako różnicę między sumą wszystkich pikseli (znaną z poprzedniego poziomu rozdzielczości) i sumą trzech pikseli przesłanych.