Understanding Image Compression

Julius Uy
Julius Uy

Follow

Apr 19, 2019 – 7 min read

Jeszcze w latach 80. XX wieku firma Microsoft opracowała agnostyczne dla urządzeń rozwiązanie renderowania obrazu dla bitmap: format plików BMP.¹ Ci, którzy wcześniej korzystali z programu Microsoft Paint, z rozkoszą przyjęliby gigantyczny rozmiar pliku uzyskany dzięki prostym pociągnięciom i kolorowym wypełnieniom.

Pomysł stojący za formatem pliku BMP polega na tym, że każdemu pikselowi przypisywana jest wartość koloru. Więc jeśli mam bitmapę 480×360 obsługującą 16 milionów kolorów (24 bity), bitmapa skończyłaby się gdzieś na północ od 4MB w rozmiarze.

Ryc. 1 – Struktura pliku obrazu bitmapowego (https://en.wikipedia.org/wiki/BMP_file_format)

To oczywiście nie jest idealne, jeśli chce się renderować wiele obrazów wysokiej jakości. Stąd należy zadać pytanie. „Czy istnieje sposób na optymalizację reprezentacji bitmapy w taki sposób, że można nadal zachować wizualną integralność obrazu, ale z mniejszą ilością zasobów do wykorzystania?”

Odpowiedź brzmi: tak. Okazuje się, że w przeważającej części użytkownicy są bardziej zainteresowani obrazami jako pomocami wizualnymi, a nie dokładnością. Na przykład, załóżmy, że otrzymam obraz mostu Golden Gate, jak pokazano poniżej:

Figure 2 – Golden Gate Bridge

Chociaż wiem, że rzeczywisty most oglądany osobiście jest o wiele bardziej szczegółowy, cokolwiek widzę tutaj, jest wystarczająco dobre dla jego celów. Więc większość ludzi jest w rzeczywistości skłonna do handlu off wizualnej integralności dla prędkości tak długo, jak kompromis jest do przyjęcia. Na przykład, jeśli degradacja w subiektywnej jakości wizualnej wynosi 1%, ale użytkownik może cieszyć się oszczędnością miejsca na poziomie 90%, jest to w większości przypadków mile widziana wymiana.

Więc, jednym z kluczowych aspektów kompresji map bitowych jest optymalizacja pod kątem wizualnej nierozróżnialności. To znaczy, usunięcie pewnych elementów obrazu, gdzie gołe oko nie jest w stanie zidentyfikować różnicy. Jest to tzw. kompresja stratna, która stanowi większość rodzajów kompresji, jakie można zaobserwować w strumieniach wideo na obrazach online. W ten sposób działają kodeki H.264, HEVC, HEIF i JPEG.

Rysunek 3 – Kompresja obrazu optymalizuje wizualną nierozróżnialność

Inne typy obrazów, takie jak PNG, są kompresowane bezstratnie. Idea jest taka, że zachowujemy pełną wizualną integralność oryginalnego obrazu, ale zużywamy mniej bajtów, aby reprezentować to samo. Istnieją jednak inne formaty plików, takie jak WebP, które obsługują zarówno kompresję stratną, jak i bezstratną. Dlaczego chcemy kompresować rzeczy bezstratnie? Jak wyżej, jest to oparte na tym, co chcemy osiągnąć dla danego obrazu. Na przykład, ikony w aplikacjach są zazwyczaj w PNG (a ostatnio w formacie grafiki wektorowej).

Bezstratna kompresja obrazu polega na większym rozmiarze pliku w przeciwieństwie do kompresji stratnej. Powodem jest przede wszystkim to, że istnieje mniej możliwości kompresji tych pierwszych niż tych drugich. Dla celów tego bloga, będziemy mówić o stratnej kompresji.

Rysunek 4 – Przegląd kompresji JPEG

Ogólne kroki podjęte w kompresji JPEG jest wykonywana do dnia dzisiejszego w kompresji wideo. Z biegiem lat algorytm został ulepszony, ale ogólne koncepcje pozostają takie same.

KROK 1. Konwersja przestrzeni kolorów

Konwersja obrazu rozpoczyna się od konwersji surowego formatu RGB obrazu do jego wartości Chroma (r i b) i Luminancji (Y). Chodzi o to, że nasze oczy są bardziej wrażliwe na zmiany w jasności niż jest to do koloru. Dlatego też, jesteśmy w stanie zmniejszyć zakres kolorów w obrazie bez zauważalnego wpływu na jakość wizualną obrazu. Odbywa się to poprzez Chroma Subsampling, jak wyjaśniono poniżej.

KROK 2. Podpróbkowanie Chroma

Wielu graczy może sobie przypomnieć, że podpróbkowanie jest jednym z możliwych pokręteł, które mogą ustawić, aby zoptymalizować swoje wrażenia w grach. Główną ideą jest to, że im więcej podpróbkowania jeden robi, tym szybciej wydajność gry jest. Dzieje się tak dlatego, że gra wymaga mniejszego zakresu kolorów do renderowania.

Podpróbkowanie chromatyczne jest oznaczane przez J:a:b z J będącym liczbą pikseli do podpróbkowania, a reprezentującym piksele górnego rzędu i b reprezentującym piksele dolnego rzędu.

Rysunek 5 – Podpróbkowanie chromatyczne

W przypadku 4:4:4 oznacza to, że w pikselach 4×2, pierwszy rząd (a) musi mieć 4 kolory i tak samo drugi rząd. W przypadku 4:2:2 oznacza to, że w pikselach 4×2 pierwszy rząd powinien być wypełniony dwoma kolorami i tak samo drugi rząd. W przypadku 4:2:0, oznacza to, że w pikselach 4×2, pierwszy rząd powinien być reprezentowany przez dwa kolory, a drugi rząd kopiuje to, co jest w pierwszym rzędzie.

Jak widać. poprzez podpróbkowanie chromatyczne, jesteśmy w stanie zmniejszyć zakres kolorów aż o 75%.

KROK 3. Dyskretna transformata kosinusowa

Kompresja JPEG jest wykonywana poprzez pocięcie oryginalnego obrazu na fragmenty 8×8 pikseli. W tym kroku przypisujemy współczynniki dla fragmentu 8×8 pikseli na podstawie sygnałów przedstawionych poniżej.

Ryc. 6 – Dyskretna transformata kosinusowa (DCT). Lewy obraz to referencja sygnału 8×8 użyta do nadania wagi oryginalnemu obrazowi. Prawy obraz to wynikowy fragment po przejściu przez DCT.

Pomysł jest taki, że im bardziej ludzkie oko przesuwa się od lewego górnego rogu odniesienia DCT do prawego dolnego, tym trudniej jest go dostrzec. Więc zazwyczaj, co się dzieje, że w przypisywaniu współczynników, górna lewa dostaje bardzo wysoką wartość i to idzie w dół, jak jeden przesuwa się w dół po przekątnej.

Tak może to wyglądać w formacie numerycznym:

Rysunek 7 – Oryginalny fragment (po lewej) Nowy fragment po zastosowaniu DCT (po prawej)

KROK 4. Kwantyzacja

Po zastosowaniu DCT, kolejnym krokiem jest kwantyzacja. Tutaj, tabela kwantyzacji jest stosowana do wynikowych wartości DCT. Tabela ta różni się w zależności od algorytmu kompresji, a niektóre programy pozwalają użytkownikowi ustawić ilość kwantyzacji, którą chce użyć. Poniżej znajduje się standardowa tabela:

Rysunek 8 – Standardowa tabela kwantyzacji

Zauważ, że cyfry rosną w miarę przesuwania się z lewego górnego rogu do prawego dolnego. Jest to zamierzone. Idea kwantyzacji polega na tym, że dane wynikowe z DCT są dzielone za pomocą tablicy kwantyzacji. Jest to miejsce, w którym skompresowany obraz traci wiele swoich danych. Ponieważ dolne prawe liczby są wysokie, większość ich wartości stanie się ostatecznie zerami po podziale. Oto jak to może wyglądać:

Rysunek 9 – Tabela kwantyzacji (po lewej) Wartości wynikowe (po prawej)

KROK 5. Kodowanie entropii przy użyciu kodowania Huffmana

Kodowanie Huffmana to ostatni krok w kompresji. Oto jak ono działa.

Załóżmy, że chcę reprezentować pewien zakres liczb za pomocą bitów. Co więcej, chcę je reprezentować w taki sposób, że zużywam najmniejszą ilość bitów na reprezentację. Jak to może być zrobione jest to, że wysoce powtarzające się liczby otrzymują niższe bity. Na przykład, jeśli zero jest reprezentowane dużo, generalnie przypisałbym mu niższe bity. Bardziej dokładne wyjaśnienie kodowania Huffmana można znaleźć tutaj.

Pomysł jest taki, że używasz mniej bitów do reprezentowania dłuższego zestawu wartości. Kodowanie Huffmana jest algorytmem kompresji bezstratnej, który jest również używany w kompresji plików tekstowych. Robiąc to, można zaoszczędzić aż 50% oryginalnego rozmiaru.

Co dalej?

Kompresja jest po prostu jedną z części równania. Kiedy jeden ma do renderowania obrazu, on musi odwrócić proces kompresji zanim onis able do renderowania obrazu na screen.

JPEGs są mniej więcej około 90% mniejsze niż jego odpowiednik bitmapy. Do dnia dzisiejszego jest to wciąż najpopularniejszy format kompresji obrazu. Nowsze algorytmy takie jak HEIF (2013) i AVIF (2018) zwiększają zakres pikseli, które można wykorzystać w algorytmie kompresji.²

Mimo popularności JPEG, nowsze formaty zapewniają lepszą kompresję. WebP, na przykład, jest około 70% rozmiaru JPEG, a mimo to nadal jest w stanie zachować wizualną integralność obrazu. Stąd, Google (firma, która opracowała WebP) została szturchanie deweloperów do ponownego kodowania swoich obrazów z JPEG do WebP. Wsparcie dla WebP jednak nadal jest mniej niż JPEG. Stąd konieczność obsługi obu formatów w rezultacie.

¹ „The BMP File Format.” Prepressure. Accessed April 19, 2019. https://www.prepressure.com/library/file-formats/bmp.

² Netflix opublikował pierwszy zestaw obrazów AVIF w 2018 roku. Od tego postu obrazy te są nadal dostępne tutaj. Firmy takie jak Firefox i Microsoft będą wspierać ten obraz wkrótce w swoich ofertach oprogramowania.

.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.