Kompresja
Kompresja Obrazu Po co kompresja Podstawowe pojęcia RLE LZ78 LZW Huffman JPEG
Po co kompresja Obraz FullHD 1920x1080 w kolorze RGB to 49766400 bity danych (5,94 MiB) Przeciętne zdjęcie 18Mpixel ~ 51,5MiB 1s filmu FullHD = 24kl * 5,94MiB = 142,56MiB Dwugodzinny film to ok 1TB 1CD (750MB) to 5s filmu BluRay (50GB) to aż 5,8 minut Dopiero dyski SATA i nowsze napędy BluRay oferują wystarczająco szybki (rzeczywisty) transfer danych. Z 4K (876MiB/s) ledwie poradzi sobie SATA 3
Kompresja Transformacja oryginalnej reprezentacji danych w inną reprezentację o mniejszej ilości bitów Główne cele kompresji Zredukowanie czasu transmisji Zawężenie wymaganego pasma przesyłania Umożliwienie archiwizacji większej ilości danych
Kompresja Rodzaje kompresji Bezstratna - Dane uzyskane z cyklu kompresja/dekompresja są identyczne z nieskompresowanym oryginałem. Stratna Dane uzyskane z cyklu kompresja/dekompresja różnią się w pewnym stopniu od nieskompresowanego oryginału. Kompresja stratna jest akceptowalna tam, gdzie tracone dane są mało istotne dla odbioru przekazu.
Kompresja
Kompresja bezstratna
Kompresja bezstratna Limit kompresji E=7,01 E=5,31
Kompresja stratna
Kompresja stratna
Kompresja stratna Średnia różnica: Zawartość strukturalna (ang. Structual Content): Znormalizowana korelacja wzajemna (ang. Normalized Cross-Correlation): N M M x N y y x f y x f AD 1 1 ), ( ), ( M x N y y x f M x N y y x f AC 1 1 2 ), ( 1 1 2 ), ( M x N y y x f M x N y y x f y x f NK 1 1 2 ), ( 1 1 ), ( ), (
Kompresja stratna M x N y M x N y y x f y x f y x f CQ 1 1 1 1 ), ( ), ( ), ( ), ( ), ( y x f y x f Max MD M x N y M x N y y x f y x f y x f IF 1 1 2 1 1 2 ), ( ), ( ), ( 1 Jakość korelacji (Correlation Quality): Maksymalna różnica (Maximum Difference) / szczytowy błąd bezwzględny (Peak Absolute Error-PAE): Wierność obrazu (Image Fidelity):
Kompresja stratna Normalizowany błąd bezwzględny (Normalized Absolute Error): Znormalizowany błąd średniokwadratowy (Normalized Mean Square Error): M x N y M x N y y x f y x f y x f NAE 1 1 1 1 ), ( ), ( ), ( IF y x f y x f y x f NMSE M x N y M x N y 1 ), ( ), ( ), ( 1 1 2 1 1 2
Kompresja ogólna zasada Bezstratna Obraz x Transformata y=t(x) próbki y koder c=c(y) Wynik (bity) c bity c dekoder y=c -1 (c) próbki y Tr. odwrotna x=t -1 (y) Obraz x T i C są w odwracalne
Kompresja ogólna zasada Stratna Obraz x Transformata y=t(x) próbki y kwantyzator q=q(y) indeksy q koder c=c(y) Wynik (bity) c bity c dekoder q=c -1 (c) próbki y dekwantyzato r y'=q -1 (q) próbki y' Tr. odwrotna x'=t -1 (y) Obraz x' T i C są w odwracalne, Q wprowadza stratność
Kompresja stratna I 1 I 2 I 3 I 4
Run-Length Encoding kodowanie długości serii Jeden z najprostszych algorytmów kompresji bezstratnej. Nie wymaga transformacji przygotowującej Niezbyt duży stopień kompresji (ok. 2:1) Bardzo szybka kompresja i dekompresja, Zakodowany strumień danych jest mało czuły na zakłócenia
Run-Length Encoding przebieg Obraz jest przeglądany liniami Jeżeli w linii wykryto ciąg pikseli o takich samych wartościach, jest on zastępowany wartością koloru i liczbą wystąpień Kodowanie musi umożliwiać odróżnienie liczby wystąpień od wartości koloru W powyższym przypadku zrealizowano to stosując zasadę: Każdy ciąg jest skracany do dwóch wystąpień po których następuje liczba kolejnych wystąpień (może być 0). W ten sposób w ciągu skompresowanym liczba wystąpień pojawia się wyłącznie po każdym wystąpieniu 2 takich samych wartości
LZ78 Opracowany przez naukowców o nazwiskach Lempel i Ziv Bazuje na wyszukiwaniu powtórzeń Powtórzenia wyszukiwane są na bazie słownika ale nie ma potrzeby przechowywania słownika jest on tworzony / odtwarzany na podstawie ciągu kompresowanego / dekompresowanego
LZ78 przebieg Założenia początkowe: Słownik jest zbiorem pustym Obraz ułożony liniami w ciąg
LZ78 przebieg Od początku obrazu do osiągnięcia końca Szukaj elementu w najdłuższego słowa w słowniku zgodnego z początkiem niezakodowanej części ciągu Gdy został znaleziony (pod indeksem n w słowniku) dołącz do niego następny element w ciągu (a) i zapisz jako kolejny element słownika. Do ciągu wynikowego dopisz parę (n, a). Przesuń się w ciągu o length(w)+1. Gdy nic nie znaleziono zapisz a (pierwszy element ciągu) jako kolejny element słownika. Do ciągu wynikowego dopisz parę (0,a). Przesuń się w ciągu o 1.
LZ78 Przykład Ciąg kompresowany: 8 210 8 210 8 210 8 210 8 Słownik: null Kod: null
LZ78 Przykład Ciąg kompresowany: 8 210 8 210 8 210 8 210 8 Słownik: Kod: 1 8 (0, 8)
LZ78 Przykład Ciąg kompresowany: 8 210 8 210 8 210 8 210 8 Słownik: Kod: 1 2 8 210 (0, 8)(0, 210)
LZ78 Przykład Ciąg kompresowany: 8 210 8 210 8 210 8 210 8 Słownik: Kod: 1 2 3 8 210 8 210 (0, 8)(0, 210)(1, 210)
LZ78 Przykład Ciąg kompresowany: 8 210 8 210 8 210 8 210 8 Słownik: Kod: 1 2 3 4 8 210 8 210 8 210 8 (0, 8)(0, 210)(1, 210)(3, 8)
LZ78 Przykład Ciąg kompresowany: 8 210 8 210 8 210 8 210 8 Słownik: Kod: 1 2 3 4 5 8 210 8 210 8 210 8 210 8 (0, 8)(0, 210)(1, 210)(3, 8)(2, 8)
LZ78 przebieg (dekompresja) Od początku skompresowanego ciągu do osiągnięcia końca Dla każdej pary (n, a) Do końca ciągu zdekompresowanego dodaj podciąg składający się ze słowa w (znalezionego pod indeksem n w słowniku) oraz wartości a. Gdy n=0 dodaj tylko a. Do słownika dodaj ciąg wa (lub tylko a dla n=0)
LZ78 Przykład Kod: (0, 8)(0, 210)(1, 210)(3, 8)(2, 8) Słownik: null Ciąg zdekompresowany: null
LZ78 Przykład Kod: (0, 8)(0, 210)(1, 210)(3, 8)(2, 8) Słownik: 1 8 Ciąg zdekompresowany: 8
LZ78 Przykład Kod: (0, 8)(0, 210)(1, 210)(3, 8)(2, 8) Słownik: 1 2 8 210 Ciąg zdekompresowany: 8 210
LZ78 Przykład Kod: (0, 8)(0, 210)(1, 210)(3, 8)(2, 8) Słownik: 1 2 3 8 210 8 210 Ciąg zdekompresowany: 8 210 8 210
LZ78 Przykład Kod: (0, 8)(0, 210)(1, 210)(3, 8)(2, 8) Słownik: 1 2 3 4 8 210 8 210 8 210 8 Ciąg zdekompresowany: 8 210 8 210 8 210 8
LZ78 Przykład Kod: (0, 8)(0, 210)(1, 210)(3, 8)(2, 8) Słownik: 1 2 3 4 5 8 210 8 210 8 210 8 210 8 Ciąg zdekompresowany: 8 210 8 210 8 210 8 210 8
LZ78 Przykład Kod: (0, 8)(0, 210)(1, 210)(3, 8)(2, 8) Słownik: 1 2 3 4 5 8 210 8 210 8 210 8 210 8 Ciąg zdekompresowany: null
LZ78 problemy Jak zapisywać ciąg Kodu (pary) Indeksy jaki zakres? Wartości stała ilość bitów dla koloru (8 lub 24) Typowe rozwiązania Zakres indeksu ustalony odgórnie, gdy zapełnimy słownik to alternatywnie: Przestajemy zapisywać nowe słowa do słownika Czyścimy słownik i kontynuujemy od zera Nadpisujemy słowa od początku słownika
LZ78 problemy Czy musimy zawsze zapisywać drugi element pary? Konieczne na początku do zapisania nieistniejącego w słowniku poziomu jasności. Na dalszym etapie już niepotrzebne a zmniejsza stopień kompresji
LZW Modyfikacja LZ78 zaproponowana przez Welsha Do ciągu Kodu zapisujemy tylko indeksy słów w słowniku Na początku słownik napełniamy wszystkimi dostępnymi wartościami poziomu jasności (0-255). Powstaje w ten sposób alfabet, z którego algorytm może korzystać w przypadku znalezienia nowego znaku. Do słownika standardowo dopisywany jest znaleziony podciąg + kolejna wartość
LZW Przykład Ciąg kompresowany: 8 210 8 210 8 210 8 210 8 Słownik: Kod: null 9 211 8 210
LZW Przykład Ciąg kompresowany: 8 210 8 210 8 210 8 210 8 Słownik: Kod: 9 9 211 257 8 210 8 210
LZW Przykład Ciąg kompresowany: 8 210 8 210 8 210 8 210 8 Słownik: Kod: 9 211 257 258 8 210 8 210 210 8 9 211
LZW Przykład Ciąg kompresowany: 8 210 8 210 8 210 8 210 8 Słownik: Kod: 9 211 257 258 259 8 210 8 210 210 8 8 210 8 9 211 257
LZW Przykład Ciąg kompresowany: 8 210 8 210 8 210 8 210 8 Słownik: Kod: 9 211 257 258 259 260 8 210 8 210 210 8 8 210 8 8 210 8 210 9 211 257 259
LZW Przykład Ciąg kompresowany: 8 210 8 210 8 210 8 210 8 Słownik: Kod: 9 211 257 258 259 260 8 210 8 210 210 8 8 210 8 8 210 8 210 9 211 257 259 258
LZW dekompresja Dekompresja napotyka problem niewystarczających danych Koder zakodowuje w i dodaje do słownika wa Dekoder odkodowuje w ale nie może dodać wa do słownika bo nie zna jeszcze wartości a Rozwiązanie: Do słownika dodawane jest niepełne słowo w?. W następnym kroku? Zastępowany jest pierwszą literą kolejnego odkodowanego fragmentu
LZW dekompresja - przebieg Na wejściu ciąg liczb Kodu k 1,,k n W słowniku umieszczone wszystkie możliwe wartości jasności (0-255) Dla i=1,2,,n Jeżeli w poprzednim kroku dodano element w? to zamień go na ws[k i ][1]. (S[k i ] element w słowniku zapisany pod indeksem k i ) Do odkodowanego tekstu dodaj na końcu S[k i ] Do słownika dodaj S[k i ]?
LZW Przykład (dekompresja) Krok 1 A Kod: 9 211 257 259 258 S[k 1 ][1] = 8 Słownik: 9 211 8 210 Ciąg zdekompresowany: null
LZW Przykład (dekompresja) Krok 1 B Kod: 9 211 257 259 258 S[k 1 ][1] = 8 Słownik: 9 211 257 8 210 8? Ciąg zdekompresowany: 8
LZW Przykład (dekompresja) Krok 2 A Kod: 9 211 257 259 258 S[k 2 ][1] = 210 Słownik: 9 211 257 8 210 8 210 Ciąg zdekompresowany: 8
LZW Przykład (dekompresja) Krok 2 B Kod: 9 211 257 259 258 S[k 2 ][1] = 210 Słownik: 9 211 257 258 8 210 8 210 210? Ciąg zdekompresowany: 8 210
LZW Przykład (dekompresja) Krok 3 A Kod: 9 211 257 259 258 S[k 3 ][1] = 8 210 Słownik: 9 211 257 258 8 210 8 210 210 8 Ciąg zdekompresowany: 8 210
LZW Przykład (dekompresja) Krok 3 B Kod: 9 211 257 259 258 S[k 3 ][1] = 8 210 Słownik: 9 211 257 258 259 8 210 8 210 210 8 8 210? Ciąg zdekompresowany: 8 210 8 210
LZW Przykład (dekompresja) Krok 4 A Kod: 9 211 257 259 258 S[k 4 ][1] = 8 210? Słownik: 9 211 257 258 259 8 210 8 210 210 8 8 210 8 Ciąg zdekompresowany: 8 210 8 210
LZW Przykład (dekompresja) Krok 4 B Kod: 9 211 257 259 258 S[k 4 ][1] = 8 210 8 Słownik: 9 211 257 258 259 260 8 210 8 210 210 8 8 210 8 8 210 8? Ciąg zdekompresowany: 8 210 8 210 8 210 8
LZW Przykład (dekompresja) Krok 5 A Kod: 9 211 257 259 258 S[k 5 ][1] = 210 8 Słownik: 9 211 257 258 259 260 8 210 8 210 210 8 8 210 8 8 210 8 210 Ciąg zdekompresowany: 8 210 8 210 8 210 8
LZW Przykład (dekompresja) Krok 5 A Kod: 9 211 257 259 258 S[k 5 ][1] = 210 8 Słownik: 9 211 257 258 259 260 8 210 8 210 210 8 8 210 8 8 210 8 210 Ciąg zdekompresowany: 8 210 8 210 8 210 8 210 8
LZW w GIF Początkowo słownik ma rozmiar 2 b+1 gdzie b jest ilością bitów indeksu (1-8). 512 słów dla standardowego indeksu 256 kolorów z tego połowa zajęta na starcie Rozmiar słownika jest podwajany po wypełnieniu aż do osiągnięcia 4096 Po dotarciu do końca dostępnego zakresu słownik przestaje być uzupełniany
Huffman Algorytm Huffmana ogłoszono w 1952r. Główna idea polega na wytworzeniu słownika zawierającego wyłącznie litery alfabetu kodowanej informacji (w przypadku grafiki pojedyncze poziomy jasności) Indeksy dla poziomów nie mają stałej długości i są dobierane tak aby najczęściej występujący w obrazie otrzymał najkrótszy indeks (np. 1 bit) Dobór kolejności realizowany na podstawie histogramu
Huffman Ale Skoro indeksy mają różną długość to jak je rozróżnić w ciągu bitów zakodowanej wiadomości? Dodanie np. unikalnego przedrostka-znacznika niweluje nam cały zysk z metody taki znacznik musiałby być długi, inaczej mógłby się powtórzyć w ciągu bitów któregoś z indeksów Rozwiązanie wprowadzenie wymogu, że żadne słowo kodowe nie może być początkiem innego słowa (tzw kodowanie prefiksowe)
Huffman Jak maszynowo wygenerować kody prefiksowe na podstawie listy prawdopodobieństw? Zbudować drzewo binarne Do każdej wartości prowadzi tylko jedna droga. Jeżeli rozgałęzienia na prawą stronę oznaczone zostaną 0 a na lewą 1 to dla każdej wartości można określić unikatowy kod binarny. Dla danej serii danych można zbudować więcej niż jedno drzewo, co oznacza, że w czasie dekompresji potrzebne jest drzewo, według którego dane zostały zakodowane (wystarczy przesłać ciąg prawdopodobieństw / histogram i odbudować drzewo)
Huffman przykład generacji kodów Wstępne posortowanie prawdopodobieństw (opcja) Źródło: Grzegorz Kraszewski SYSTEMY MULTIMEDIALNE wykład 3
Huffman przykład generacji kodów Elementy ciągu są korzeniami n drzew Redukujemy kolejno ilość drzew zamieniając dwa korzenie na nowy o prawdopodobieństwie = sumie prawdopodobieństw usuniętych Usunięte korzenie stają się gałęziami/liściami nowego korzenia W tym przykładzie do redukcji wybieramy dwa najmniejsze prawdopodobieństwa z bieżącego ciągu Źródło: Grzegorz Kraszewski SYSTEMY MULTIMEDIALNE wykład 3
Huffman przykład generacji kodów W efekcie otrzymujemy jedno drzewo, którego korzeń ma prawdopodobieństwo 1 a liściami są wszystkie prawdopodobieństwa/poziomy jasności Opisujemy drzewo wartościami bitów (0 zawsze po tej samej stronie) Kod poziomu jasności to konkatenacja bitów od korzenia do odpowiedniego liścia Źródło: mgr inż. Grzegorz Kraszewski SYSTEMY MULTIMEDIALNE wykład 3
Huffman przykład generacji kodów Źródło: Grzegorz Kraszewski SYSTEMY MULTIMEDIALNE wykład 3
Huffman przykład generacji kodów (duża różnica prawdopodobieństw) Źródło: Grzegorz Kraszewski SYSTEMY MULTIMEDIALNE wykład 3
Huffman - jakość Dla tego przypadku entropia wynosi 1,68 a średnia ilość bitów kodu 1,694 (znowu dobry wynik) Jednak nie zawsze Huffman radzi sobie tak dobrze. W przypadku powtarzających się dłuższych sekwencji algorytm LZW/LZ78 wychwyci tą sekwencję i zapisze ją w słowniku (następnie sekwencje sekwencji ) Algorytm Huffmana będzie powtarzał kodowanie każdej podsekwencji z powodu braku słów wieloznakowych w słowniku
Huffman - jakość Z drugiej strony omawiany przykład przedstawia sytuację gdy prawdopodobieństwa wystąpienia poszczególnych stanów są zbliżone do siebie co spowodowało równomierne rozłożenie ilości bitów na poszczególne kody Gdyby tak było zawsze nie było by potrzeby generowania drzewa binarnego
JPEG Opracowanie formatu przez Joint Photographic Expert Group - 1986 Wprowadzenie jako standard ISO 1991 Kompresja stratna bazująca na dziedzinie częstotliwościowej
JPEG przebieg algorytmu 1. Konwersja obrazu kolorowego do składowej jasności i sk. Koloru (YIQ) 2. Podział obrazu na bloki (8x8) Dla każdego bloku 3. Obliczenie DCT dla bloku 4. Kwantyzacja wyników 5. Konwersja tablicy wyników na wektor 6. Zakodowanie wektora wyników
JPEG Konwersja obrazu kolorowego do składowej jasności i sk. Koloru (Y C b C r ) Konwersja RGB do Y C b C r jest dokonywana przekształceniem Y = 0.299R + 0.587G + 0.114B C b = 0.169R 0.331G + 0.500B = 0.564(B Y ) C r = 0.500R 0.418G 0.081B = 0.713(R Y ) Wynikiem są tablica luminancji Y i 2 tablice chrominancji C b C r Konwersja jest stratna bo wartości poszczególnych składowych są zaokrąglane Dodatkowo do C b i C r dodawana jest wartość 128
JPEG Podział obrazu na bloki (8x8) Każda z tablic jest dzielona na bloki (podtablice) o wymiarach 8x8 Indeksowanych x=(0,1,,7) y=(0,1,,7) Dalsze operacje przeprowadzane są dla każdego z bloków oddzielnie
JPEG Obliczenie DCT dla bloku Dyskretna Transformata Kosinusowa dla bloku 8x8 wyraża się wzorem u, v pozycja w tablicy 8x8 wyników Bardzo ważna cecha: DCT jest odwracalna
JPEG DCT - idea Zamiast rozłożenia przestrzennego wartości otrzymujemy rozkład częstotliwości tego kawałka obrazu Składowa stała Źródło: Jacek Jarnicki Kompresja obrazów statycznych algorytm JPEG
JPEG DCT - idea Zamiast rozłożenia przestrzennego wartości otrzymujemy rozkład częstotliwości tego kawałka obrazu Źródło: Jacek Jarnicki Kompresja obrazów statycznych algorytm JPEG
JPEG DCT Z reguły DCT bloku obrazu będzie przypominać taki wykres Źródło: Jacek Jarnicki Kompresja obrazów statycznych algorytm JPEG
JPEG Obliczenie DCT dla bloku - przykład f(x,y) F(u,v) Zakres wartości F(u,v) wielokrotnie większy od f(x,y) to gdzie kompresja?
JPEG przebieg algorytmu Kwantyzacja wyników Przykładowy efekt kwantyzacji
JPEG przebieg algorytmu Konwersja tablicy wyników na wektor Odczyt wartości z tablicy algorytmem Zig-Zag Powstaje wektor zawierający długie ciągi zer, pierwsza wartość to tzw. Składowa stała (DC)
Tak przygotowany ciąg koduje się metodą bezstratną Huffmana
Kod A Kod B Kod A Kod B Kod A Kod B
JPEG przebieg algorytmu Zakodowanie wektora składowych częstotliwościowych Kod A Kod B Kod A Kod B Kod A Kod B
JPEG przebieg algorytmu Zakodowanie wektora składowych częstotliwościowych
JPEG przebieg algorytmu Zakodowanie wektora składowych częstotliwościowych Kod A Kod B Kod A Kod B Kod A Kod B
Zadanie referatowe Kompresja PNG Kompresja JPG2000