Pochopení komprese obrazu

Julius Uy
Julius Uy

Sledovat

19. dubna, 2019 – 7 minut čtení

V 80. letech minulého století vyvinula společnost Microsoft řešení pro agnostické vykreslování bitmapových obrázků na zařízení: Formát souborů BMP.¹ Ti, kdo dříve používali program Microsoft Paint, si mohli vychutnat gigantickou velikost souboru vytvořeného z jednoduchých tahů a barevných výplní.

Myšlenka formátu souborů BMP spočívá v tom, že každému pixelu je přiřazena hodnota barvy. Pokud tedy mám bitmapu o rozměrech 480×360, která podporuje 16 milionů barev (24 bitů), bitmapa by nakonec měla velikost někde na sever od 4 MB.

Obrázek 1 – Struktura souboru bitmapového obrázku (https://en.wikipedia.org/wiki/BMP_file_format)

To samozřejmě není ideální, pokud chceme vykreslit více kvalitních obrázků. Proto je třeba si položit otázku. „Existuje způsob, jak optimalizovat bitmapovou reprezentaci tak, aby bylo možné stále zachovat vizuální integritu obrázku, ale s menší spotřebou prostředků?“

Odpověď zní ano. Ukazuje se, že uživatele většinou zajímají spíše obrázky jako vizuální pomůcky než důkladnost. Předpokládejme například, že dostanu obrázek mostu Golden Gate, jak je uvedeno níže:

Obrázek 2 – Golden Gate Bridge

Ačkoli vím, že skutečný most při osobním pohledu obsahuje mnohem více detailů, to, co vidím zde, je pro jeho účely dostatečné. Takže většina lidí je vlastně ochotna vyměnit vizuální integritu za rychlost, pokud je kompromis přijatelný. Pokud je například zhoršení subjektivní vizuální kvality 1 %, ale uživatel si užije 90% úsporu místa, je to většinou vítaný kompromis.

Jedním z klíčových hledisek při kompresi bitmap je tedy optimalizace pro vizuální nerozlišitelnost. To znamená odstranění určitých prvků obrazu, u kterých pouhé oko není schopno identifikovat rozdíl. Tomu se říká ztrátová komprese, která představuje většinu typů komprese, s nimiž se setkáváme při streamování videa na internetu. Takto fungují kodeky H.264, HEVC, HEIF a JPEG.

Obrázek 3 – Komprese obrázků optimalizovaná pro vizuální nerozlišitelnost

Jiné typy obrázků, například PNG, jsou komprimovány bezeztrátově. Jde o to, že se zachovává plná vizuální integrita původního obrázku, ale spotřebuje se méně bajtů na reprezentaci téhož. Přesto existují další formáty souborů, například WebP, které podporují jak ztrátovou, tak bezeztrátovou kompresi. Proč chceme komprimovat bezeztrátově? Jak je uvedeno výše, vychází to z toho, čeho chceme pro obrázek dosáhnout. Například ikony v aplikacích jsou obvykle ve formátu PNG (a v poslední době i ve vektorové grafice).

Bezztrátová komprese obrázků spočívá ve větší velikosti souboru na rozdíl od ztrátové komprese. Důvodem je především to, že v prvním případě existuje méně možností komprese než ve druhém. Pro účely tohoto blogu budeme hovořit o ztrátové kompresi.

Obrázek 4 – Přehled komprese JPEG

Obecné kroky při kompresi JPEG se dodnes provádějí při kompresi videa. V průběhu let se algoritmus zdokonalil, ale obecné koncepty zůstávají stejné.

KROK 1. Převod barevného prostoru

Převod obrazu začíná převodem surového formátu RGB na jeho hodnoty Chroma (r a b) a Luminance (Y). Jde o to, že naše oči jsou citlivější na změny světelnosti než na barvy. Proto jsme vlastně schopni snížit rozsah barev v obrázku, aniž by to znatelně ovlivnilo vizuální kvalitu obrázku. To se provádí pomocí podvzorkování chromatičnosti, jak je vysvětleno níže.

KROK 2. Podvzorkování chromatičnosti

Mnozí hráči si možná vzpomenou, že podvzorkování patří mezi možné knoflíky, které mohou nastavit pro optimalizaci herního zážitku. Hlavní myšlenkou je, že čím více podvzorkování člověk provede, tím rychlejší je herní výkon. Je to proto, že hra potřebuje k vykreslení menší rozsah barev.

Podvzorkování barev se značí J:a:b, přičemž J je počet pixelů pro podvzorkování, a představuje pixely horní řady a b pixely dolní řady.

Obrázek 5 – Podvzorkování chromatičnosti

V případě 4:4:4 to znamená, že v pixelech 4×2 musí mít první řádek (a) 4 barvy a stejně tak druhý řádek. V případě 4:2:2 to znamená, že ve 4×2 pixelech musí mít první řádek dvě barvy a stejně tak i druhý řádek. V případě 4:2:0 to znamená, že ve 4×2 pixelech by měl být první řádek reprezentován dvěma barvami a druhý řádek kopíruje to, co je na prvním řádku.

Jak vidíte. pomocí podvzorkování barev je možné snížit rozsah barev až o 75 %.

KROK 3. Diskrétní kosinová transformace

Komprese JPEG se provádí rozřezáním původního obrazu na kousky 8×8 pixelů. V tomto kroku přiřadíme koeficienty pro kousek 8×8 na základě níže uvedených signálů.

Obrázek 6 – Diskrétní kosinová transformace (DCT). Levý obrázek je referenční signál 8×8, který se používá k odlehčení původního obrázku. Pravý obrázek je výsledný kousek po průchodu DCT.

Jde o to, že čím více se lidské oko pohybuje od levého horního okraje reference DCT k pravému dolnímu, tím obtížněji ji vnímá. Obvykle tedy dochází k tomu, že při přiřazování koeficientů dostane levý horní roh velmi vysokou hodnotu a ta klesá, jak se člověk pohybuje diagonálně dolů.

Takto může vypadat situace v číselném formátu:

Obrázek 7 – Původní kus (vlevo) Nový kus po aplikaci DCT (vpravo)

KROK 4. Kvantizace

Po aplikaci DCT se další krok nazývá kvantizace. Zde se na výsledné hodnoty DCT aplikuje kvantizační tabulka. Tato tabulka se u jednotlivých kompresních algoritmů liší a některé programy umožňují uživateli nastavit požadované množství kvantizace. Níže je uvedena standardní tabulka:

Obrázek 8 – Standardní kvantizační tabulka

Všimněte si, že číslice se zvyšují, jak se postupuje od levého horního rohu k pravému dolnímu. To je záměrné. Podstata kvantizace spočívá v tom, že výsledná data z DCT se rozdělí pomocí kvantizační tabulky. Zde komprimovaný obraz ztrácí velkou část svých dat. Protože čísla vpravo dole jsou vysoká, většina jeho hodnot se po dělení nakonec stane nulou. Takto to může vypadat:

Obrázek 9 – Kvantizační tabulka (vlevo) Výsledné hodnoty (vpravo)

KROK 5. Entropické kódování pomocí Huffmanova kódování

Huffmanovo kódování je poslední krok komprese. Zde je uvedeno, jak funguje.

Předpokládejme, že chci reprezentovat řadu čísel pomocí bitů. Navíc je chci reprezentovat tak, abych na reprezentaci spotřeboval co nejméně bitů. Jak by se to dalo udělat, je, že vysoce opakovaným číslům se přidělí nižší bity. Například pokud je hodně reprezentována nula, obecně bych jí přiřadil nižší bity. Podrobnější vysvětlení Huffmanova kódování najdete zde:

Jde o to, že na reprezentaci delší množiny hodnot spotřebujete méně bitů. Huffmanovo kódování je bezeztrátový kompresní algoritmus, který se používá také při kompresi textových souborů. Tímto postupem je možné ušetřit až 50 % původní velikosti.

Co dál?

Komprese je pouze jednou částí rovnice. Když má člověk obrázek vykreslit, musí proces komprese obrátit, než je schopen obrázek vykreslit na obrazovku.

JPEG je zhruba o 90 % menší než jeho bitmapový protějšek. Dodnes je to stále nejoblíbenější dostupný formát komprese obrázků. Novější algoritmy, jako je HEIF (2013) a AVIF (2018), zvětšují rozsah pixelů, které lze použít pro kompresní algoritmus.²

I přes popularitu formátu JPEG poskytují novější formáty lepší kompresi. Například formát WebP má obecně přibližně 70 % velikosti formátu JPEG, a přesto je schopen zachovat vizuální integritu obrazu. Proto Google (společnost, která vyvinula WebP) pobízí vývojáře, aby překódovali své obrázky z JPEG do WebP. Podpora WebP je však stále menší než u JPEG. Proto je ve výsledku nutné podporovat oba formáty.

¹ „Formát souborů BMP“. Předtisková příprava. Přístupné 19. dubna 2019. https://www.prepressure.com/library/file-formats/bmp.

² Společnost Netflix zveřejnila první sadu obrázků AVIF v roce 2018. V době zveřejnění tohoto příspěvku jsou tyto obrázky stále přístupné zde. Společnosti jako Firefox a Microsoft budou tento obraz brzy podporovat ve svých softwarových nabídkách.

.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna.