Ako funguje JPG

Ako funguje JPG

Formát súboru JPG bol jedným z technologicky najpôsobivejších pokrokov v kompresii obrazu, ktorý sa na scéne objavil v roku 1992. Odvtedy predstavuje dominantnú silu v reprezentácii obrázkov vo foto kvalite na internete. A to z dobrého dôvodu. Veľká časť technológie, ktorá stojí za tým, ako JPG funguje, je mimoriadne zložitá a vyžaduje pevné pochopenie toho, ako sa ľudské oko prispôsobuje vnímaniu farieb a hrán.

A keďže se zajímám o takové věci (a vy také, pokud to čtete), chtěl jsem rozebrat, jak funguje kódování JPG, abychom mohli lépe pochopit, jak se vytvářejí menší soubory JPG.

PODSTATA

Schéma kompresie JPG je rozdelená do niekoľkých fáz. Obrázok nižšie ich popisuje na vysokej úrovni a my si prejdeme každú fázu nižšie.

Konverzia farebného priestoru

Jedným z kľúčových princípov stratovej kompresie dát je, že ľudské senzory nie sú také presné ako výpočtové systémy. Ľudské oko má vedecky iba fyzickú schopnosť rozlíšiť asi 10 miliónov rôznych farieb. Existuje však veľa vecí, ktoré môžu ovplyvniť to, ako ľudské oko vníma farbu; dokonale zvýraznené farebnými ilúziami alebo tým, že tieto šaty zlomili internet. Podstatou je, že s ľudským okom sa dá pekne manipulovať, pokiaľ ide o farby, ktoré vníma.

Kvantovanie je formou tohto efektu pri stratovej kompresii obrazu, JPG k tomu však pristupuje odlišne: farebné modely . Farebný priestor je špecifická organizácia farieb, a jej farebný model reprezentuje matematický vzorec pre to, ako sú zastúpené tieto farby (napr trojíc v RGB, alebo štvorlôžkových v CMYK).

Na tomto procese je silné to, že môžete prevádzať z jedného farebného modelu na druhý , čo znamená, že môžete meniť matematické znázornenie danej farby s úplne odlišnou sadou číselných hodnôt.

Napríklad nižšie je konkrétna farba a je to znázornenie vo farebných modeloch RGB a CMYK. Pre ľudské oko majú rovnakú farbu, ale môžu byť znázornené pomocou inej sady číselných hodnôt.

JPG prevádza z RGB na farebný model Y, Cb, Cr; Pozostáva z Luminance (Y), Chroma Blue (Cb) a Chroma Red (Cr). Dôvodom je to, že psycho-vizuálne experimenty (aka ako mozog pracuje s informáciami, ktoré vidí oko) ukazujú, že ľudské oko je citlivejšie na jas ako na chrominanciu, čo znamená, že môžeme zanedbávať väčšie zmeny v chrominancii bez toho, aby sme ovplyvnili našu vnímanie obrazu. Preto môžeme urobiť agresívne zmeny v kanáloch CbCr skôr, ako si to ľudské oko všimne.

Prevzorkovanie

Jedným zo zaujímavých výsledkov farebného priestoru YCbCr je, že výsledné kanály Cb / Cr majú menej jemnozrnných detailov; obsahujú menej informácií ako kanál Y.

Výsledkom je, že algoritmus JPG zmení veľkosť kanálov Cb a Cr na približne ¼ pôvodnú veľkosť (všimnite si, že je tu určitá nuance v tom, ako sa to robí, že tu to nepokrývam ...), čo sa nazýva prevzorkovanie .

Tu je dôležité poznamenať, že prevzorkovanie je stratový proces kompresie (nebudete môcť získať presné farby zdroja, ale iba približnú aproximáciu), ale jeho celkový vplyv na vizuálne komponenty ľudskej vizuálnej kôry je minimálny. Luma (Y) je miesto, kde sú zaujímavé veci, a pretože iba preberáme vzorky kanálov CbCr, vplyv na vizuálny systém je malý.

Obrázok rozdelený na 8x8 blokov pixelov

Odteraz robí JPG všetky operácie s blokmi pixelov 8x8. Je to tak preto, lebo všeobecne očakávame, že v blokoch 8x8 nie je veľa rozdielov, dokonca ani pri veľmi zložitých fotografiách existuje tendencia k istej podobnosti v miestnych oblastiach; táto podobnosť neskôr využijeme pri našej kompresii.

Stojí za zmienku, že v tomto okamihu predstavujeme jeden z prvých bežných „artefaktov“ kódovania JPG. „Farebné krvácanie“ je miesto, kde farby pozdĺž ostrých hrán môžu „krvácať“ na druhú stranu. Je to tak preto, lebo v chrominančných kanáloch, ktoré vyjadrujú farbu pixelov, bol každý blok so 4 pixelmi spriemerovaný do jednej farby a niektoré z týchto blokov prechádzajú cez ostrú hranu.

Diskrétna kosínová transformácia

Až do tohto bodu boli veci dosť krotké. Farebné priestory, prevzorkovanie a blokovanie sú vo svete kompresie obrázkov jednoduché. Ale teraz ... teraz sa ukazuje skutočná matematika.

Kľúčovou súčasťou transformácie DCT je to, že predpokladá, že akýkoľvek číselný signál je možné znovu vytvoriť pomocou kombinácie kosínusových funkcií.

Napríklad, ak máme tento graf nižšie:

Vidíte, že je to vlastne súčet cos (x) + cos (2x) + cos (4x)

Možno lepšou ukážkou toho je skutočné dekódovanie obrázka, ktoré má rad kosínusových funkcií v 2D priestore. Na ukážku uvádzam jeden z najúžasnejších súborov GIF na internete: kódovanie bloku pixelov 8x8 pomocou kosínusov v 2D priestore:

To, čo tu sledujete, je rekonštrukcia obrázka (panel úplne vľavo). Pre každý snímok vezmeme novú základnú hodnotu (pravý panel) a vynásobíme ju váhovou hodnotou (text na pravom paneli), čím sa vytvorí príspevok k obrázku (stredný panel).

Ako vidíte, sčítaním rôznych kosínusových hodnôt proti váhe môžeme zrekonštruovať náš pôvodný obrázok (celkom dobre ...)

Toto je základné pozadie fungovania diskrétnej kosínusovej transformácie. Myšlienka je taká, že akýkoľvek blok 8x8 môže byť reprezentovaný ako súčet vážených kosínových transformácií, na rôznych frekvenciách. Trik v tejto celej veci spočíva v zistení, aké kosínové vstupy sa majú použiť, a ako by sa mali spolu vážiť.

Ukázalo sa, že problém „ čo majú byť použité kosíny“ je dosť ľahký; Po mnohých testovaniach bola za účelom dosiahnutia najlepších výsledkov vybraná sada kosínusových hodnôt, ktoré sú našimi základnými funkciami a sú vizualizované na obrázku nižšie.

Pokiaľ ide o problém „ako by sa mali vážiť spolu“, jednoducho (HA!) Použite tento vzorec.

Ušetrím vás, čo všetky tie hodnoty znamenajú, môžete si ich vyhľadať na stránke wikipedia.

Základným výsledkom je, že pre blok pixelov 8x8 v každom farebnom kanáli vygenerovanie vyššie uvedeného vzorca a základných funkcií vygeneruje novú maticu 8x8, ktorá predstavuje váhy, ktoré sa majú použiť počas rekonštrukcie. Tu je obrázok postupu:

Táto matica, G, predstavuje základné váhy, ktoré sa majú použiť na rekonštrukciu obrázka (malá desatinná hodnota v pravej dolnej časti animácie vyššie). V podstate pre každý základ to vynásobíme váhou v tejto matici, zhrnieme to celé a získame výsledný obraz.

V tomto okamihu už nepracujeme vo farebných priestoroch, ale priamo s G Matrixom (základné váhy), ďalšia kompresia sa vykonáva priamo na tejto matici.

Problém tu však je, že sme teraz previedli celočíselné hodnoty zarovnané do bajtov na reálne čísla. Čo efektívne nafukuje naše informácie (pohybuje sa od 1 bajtu k 1 floatu (4 bajty)). Aby sme to vyriešili a začali produkovať výraznejšiu kompresiu, prešli sme do fázy kvantovania.

Kvantovanie

Nechceme teda komprimovať údaje s pohyblivou rádovou čiarkou. To by nafúklo náš prúd a nebolo by efektívne. Za týmto účelom by sme radi našli spôsob, ako previesť váhovú maticu späť na hodnoty v rozsahu [0,255]. Priamo by sme to mohli urobiť tak, že nájdeme min / max hodnotu pre maticu (-415,38, respektíve 77,13) a vydelíme každé číslo v tomto rozsahu, aby sme získali hodnotu medzi [0,1], ktorú vynásobíme 255 aby sme dostali našu konečnú hodnotu.

Napríklad: [34,12 - -415,38] / [77,13 - -415,38] * 255 = 232

To funguje, ale kompromisom je výrazné zníženie presnosti. Toto zmena mierky spôsobí nerovnomerné rozloženie hodnôt, výsledkom čoho je výrazná vizuálna strata obrazu.

Namiesto toho sa JPG vydá inou cestou. Namiesto použitia rozsahu hodnôt v matici ako jej mierky sa namiesto nej používa predpočítaná matica kvantizačných faktorov. Tieto QF nemusia byť súčasťou streamu, môžu byť skôr súčasťou samotného kodeku.

Tento príklad ukazuje bežne používanú maticu kvantizačných faktorov, jednu pre každý základný obraz,

Teraz používame matice Q a G na výpočet našej kvantizovanej matice koeficientov DCT:

Napríklad pomocou hodnôt G [0,0] = - 415,37 a Q [0,0] = 16:

Výsledkom je konečná matica:

Pozorujte, o koľko sa matica zjednoduší - teraz obsahuje veľké množstvo položiek, ktoré sú malé alebo nulové, čo uľahčuje jej kompresiu.

Ako rýchle riešenie použijeme tento proces na kanály Y, CbCr nezávisle a ako také potrebujeme dve rôzne matice: jednu pre Y a druhú pre C kanály:

Kvantizácia komprimuje obraz dvoma dôležitými spôsobmi: jedným, obmedzuje efektívny rozsah váh a znižuje počet bitov potrebných na ich reprezentáciu. Dve, ​​veľa z váh sa stáva rovnakých alebo nulových, čo zlepšuje kompresiu v treťom kroku, entropické kódovanie.

Kvantizácia je ako taký primárnym zdrojom artefaktov JPEG. Pretože obrázky vpravo dole majú tendenciu mať najväčšie kvantizačné delitele, artefakty JPEG budú mať tendenciu pripomínať kombinácie týchto obrázkov. Maticu kvantizačných faktorov je možné priamo riadiť zmenou „úrovne kvality“ JPEG, ktorá zvyšuje jeho hodnoty nahor alebo nadol (o tom sa budeme baviť za minútu)

Kompresia

Teraz sme späť vo svete celočíselných hodnôt a môžeme pokročiť vpred s aplikovaním bezstratovej kompresnej fázy na naše bloky. Pri pohľade na naše transformované údaje by ste si však mali všimnúť niečo zaujímavé:

Postupom z ľavého horného rohu do pravého dolného rohu sa zvyšuje frekvencia núl. Vyzerá to ako hlavný podozrivý pre kódovanie dĺžky behu. Objednávky hlavných a stĺpcových riadkov tu však nie sú ideálne, pretože by to preložilo tieto série núl, skôr než by ich spojili všetky dohromady.

Namiesto toho začneme ľavým horným rohom a cik-cak v diagonálnom vzore naprieč maticou, ideme tam a späť, až kým sa nedostaneme do pravého dolného rohu.

Výsledok našej lumovej matice v tomto poradí sa stáva:

−26, −3,0, −3, −2, −6,2, −4,1, −3,1,1,5,1,2, −1,1, −1,2,0,0 , 0,0,0, -1, -1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 , 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

Keď sú údaje v tomto formáte, ďalšie kroky sú priame: vykonajte RLE v sekvencii a potom na výsledky použite štatistický kódovač (Huffman / Arithmetic / ANS).

A Boom. Váš blok je teraz kódovaný do formátu JPG.

Pochopenie parametra kvality

Teraz, keď rozumiete tomu, ako sa súbory JPG skutočne vytvárajú, stojí za to prehodnotiť koncept parametra kvality , ktorý bežne vidíte pri exportovaní obrázkov JPG z Photoshopu (alebo čo už).

Tento parameter, ktorý budeme nazývať q, je celé číslo od 1 do 100. O q by ste mali uvažovať ako o meradle kvality obrázka: vyššie hodnoty q zodpovedajú kvalitnejším obrázkom a väčším veľkostiam súborov.

Táto hodnota kvality sa používa počas fázy kvantovania, aby sa kvantizačné faktory primerane škálovali. Takže na základe základnej hmotnosti sa krok kvantovania teraz podobá na guľatý (Gi, k / alfa * Qi, k)

Kde sa v dôsledku parametra kvality vytvorí symbol alfa .

Keď sa zvýši buď alfa alebo Q [x, y] (pamätajte, že veľké hodnoty alfa zodpovedajú menším hodnotám parametra kvality q), dôjde k strate ďalších informácií a zmenšeniu veľkosti súboru .

Ak teda chcete menší súbor, za cenu viacerých vizuálnych artefaktov môžete počas fázy exportu nastaviť nižšiu hodnotu kvality.

Všimnite si vyššie na obrázku s najnižšou kvalitou, ako vidíme jasné príznaky fázy blokovania, ako aj fázy kvantovania.

Asi najdôležitejšie je, že sa parameter kvality líši v závislosti od obrázka . Pretože každý obrázok je jedinečný a predstavuje rôzne typy vizuálnych artefaktov, bude aj hodnota Q jedinečná.

Záver

Keď pochopíte, ako funguje algoritmus JPG, bude zrejmé niekoľko vecí:

  1. Správna hodnota kvality podľa obrázka je dôležitá na nájdenie kompromisu medzi vizuálnou kvalitou a veľkosťou súboru.
  2. Pretože tento proces je založený na blokoch, artefakty sa budú zvyčajne vyskytovať v blokovanosti alebo „zvonení“
  3. Pretože sa spracované bloky navzájom nemiešajú, JPG všeobecne ignoruje možnosť komprimovať veľké časti podobných blokov dohromady. Riešenie tohto problému je vec, ktorú formát WebP dokáže robiť dobre.

A ak sa chcete s týmto všetkým pohrať sami, celé toto šialenstvo sa dá zredukovať na ~ 1 000 riadkový súbor.

Ahoj!

Chcete vedieť, ako zmenšiť svoje súbory JPG?

Chcete vedieť, ako súbory PNG fungujú alebo ako ich zmenšiť?

Chcete viac dobrých údajov o kompresii údajov? Kúpte si moju knihu!