Kako JPG radi

Kako JPG radi

JPG format datoteke bio je jedan od tehnološki najimpresivnijih pomaka u kompresiji slika koji se pojavio na sceni 1992. Od tada je dominantna snaga u predstavljanju slika kvalitetne fotografije na Internetu. I to s dobrim razlogom. Većina tehnologije koja stoji iza JPG-a izuzetno je složena i zahtijeva čvrsto razumijevanje kako se ljudsko oko prilagođava percepciji boja i rubova.

A budući da se ja bavim tim pomalo stvarima (a i vi ste, ako ovo čitate), htio sam razložiti kako funkcionira JPG kodiranje, kako bismo mogli bolje razumjeti kako napraviti manje JPG datoteke.

POVRATAK

Shema kompresije JPG podijeljena je u nekoliko faza. Slika u nastavku opisuje ih na visokoj razini, a mi ćemo proći kroz svaku fazu u nastavku.

Konverzija prostora boja

Jedno od ključnih načela kompresije podataka s gubicima je da ljudski senzori nisu toliko precizni kao računalni sustavi. Znanstveno, ljudsko oko ima samo fizičku sposobnost da razlikuje oko 10 milijuna različitih boja. Međutim, postoji mnogo stvari koje mogu utjecati na to kako ljudsko oko opaža boju; savršeno istaknuto iluzijama u boji, ili činjenicom da je ova haljina razbila internet. Suština je u tome da se ljudskim okom može lijepo manipulirati s obzirom na boje koje opaža.

Kvantizacija je oblik ovog učinka u kompresiji slike s gubicima, međutim JPG tome zauzima drugačiji pristup: modeli u boji . Prostor boja posebna je organizacija boja, a njegov model boja predstavlja matematičku formulu kako su te boje predstavljene (npr. Trojke u RGB-u ili četverostruke u CMYK-u).

Ono što je moćno u ovom procesu je to što možete pretvoriti iz jednog modela boje u drugi , što znači da možete promijeniti matematički prikaz dane boje s potpuno drugačijim skupom numeričkih vrijednosti.

Primjerice, dolje je određena boja, koja je zastupljena u modelima boja RGB i CMYK, iste su boje za ljudsko oko, ali mogu se predstaviti različitim skupom numeričkih vrijednosti.

JPG pretvara iz RGB u model boje Y, Cb, Cr; Sadrži Luminance (Y), Chroma Blue (Cb) i Chroma Red (Cr). Razlog tome je taj što psiho-vizualni eksperimenti (zvani kako mozak radi s informacijama koje oko vidi) pokazuju da je ljudsko oko osjetljivije na osvjetljenje nego na krominiranost, što znači da možemo zanemariti veće promjene u kromaciji bez utjecaja na naš percepcija slike. Kao takvi, možemo napraviti agresivne promjene na CbCr kanalima prije nego što to primijeti ljudsko oko.

Donje uzorkovanje

Jedan od zanimljivih rezultata prostora boja YCbCr jest da rezultirajući Cb / Cr kanali imaju manje sitnozrnatih detalja; sadrže manje informacija nego Y kanal.

Kao rezultat, JPG algoritam mijenja veličinu Cb i Cr kanala na približno ¼ njihove izvorne veličine (imajte na umu da postoji neka nijansa u načinu na koji se to radi, a što ovdje ne pokrivam ...), što se naziva downsampling .

Ovdje je važno napomenuti da je smanjenje uzorkovanja postupak kompresije s gubitkom (nećete moći oporaviti točne izvorne boje, već samo blisku aproksimaciju), ali sveukupni utjecaj na vizualne komponente ljudskog vidnog korteksa minimalan je. Luma (Y) je mjesto gdje su zanimljive stvari, a budući da samo uzorkujemo CbCr kanale, utjecaj na vizualni sustav je nizak.

Slika podijeljena na 8x8 blokova piksela

Odsad nadalje, JPG obavlja sve operacije na 8x8 blokova piksela. To je učinjeno jer općenito očekujemo da nema puno razlike u blokovima 8x8, čak i na vrlo složenim fotografijama, postoji tendencija da postoji neka sličnost u lokalnim područjima; ova sličnost je ono što ćemo kasnije iskoristiti tijekom kompresije.

Vrijedno je napomenuti da u ovom trenutku uvodimo jedan od prvih uobičajenih "artefakata" JPG kodiranja. "Krvarenje bojom" je mjesto gdje boje duž oštrih rubova mogu "iskrvariti" na drugu stranu. To je zato što su kanali za kromiranje, koji izražavaju boju piksela, imali svaki blok od 4 piksela u prosjeku u jednu boju, a neki od tih blokova prelaze oštar rub.

Diskretna transformacija kosinusa

Do ovog trenutka stvari su bile prilično pitome. Prostori boja, smanjenje uzorka i blokiranje jednostavne su stvari u svijetu kompresije slika. Ali sada ... sada se pojavljuje prava matematika.

Ključna komponenta DCT transformacije je u tome što pretpostavlja da se bilo koji numerički signal može ponovno stvoriti kombinacijom kosinusnih funkcija.

Na primjer, ako imamo ovaj grafikon u nastavku:

Možete vidjeti da je to zapravo zbroj cos (x) + cos (2x) + cos (4x)

Možda je bolji prikaz ovoga stvarno dekodiranje slike s obzirom na niz kosinusnih funkcija u 2D prostoru. Da bih to pokazao, predstavljam jedan od najnevjerojatnijih GIF-ova na internetu: kodiranje bloka piksela 8x8 pomoću kosinusa u 2D prostoru:

Ono što ovdje gledate je rekonstrukcija slike (krajnja lijeva ploča). Za svaki kadar uzmemo novu osnovnu vrijednost (desna ploča) i pomnožimo je s vrijednošću težine (tekst desne ploče) da bismo dali doprinos slici (središnja ploča).

Kao što vidite, zbrajanjem različitih vrijednosti kosinusa u odnosu na uteg, možemo rekonstruirati izvornu sliku (prilično dobro ...)

Ovo je temeljna podloga za funkcioniranje diskretne kosinusne transformacije. Ideja je da bilo koji blok 8x8 može biti predstavljen kao zbroj ponderiranih kosinusnih transformacija, na različitim frekvencijama. Trik u cijeloj ovoj stvari je odgonetnuti koje kosinusne ulaze koristiti i kako ih treba zajedno vagati.

Ispostavilo se da je problem " koje kosinuse koristiti" prilično jednostavan; Nakon puno ispitivanja, odabran je niz kosinusnih vrijednosti kako bi se postigli najbolji rezultati, one su naše osnovne funkcije i prikazane na donjoj slici.

Što se tiče problema "kako ih treba zajedno vagati", jednostavno (HA!) Primijenite ovu formulu.

Poštedjet ću vas što sve te vrijednosti znače, možete ih potražiti na wikipedia stranici.

Osnovni je rezultat da će za blok od 8x8 piksela u svakom kanalu boje, primjenom gornje formule i osnovnih funkcija generirati novu matricu 8x8, koja predstavlja težine koje će se koristiti tijekom rekonstrukcije. Evo grafike postupka:

Ova matrica, G, predstavlja osnovne utege koji se koriste za rekonstrukciju slike (mala decimalna vrijednost u donjoj desnoj strani animacije iznad). U osnovi, za svaku bazu pomnožimo je s težinom u ovoj matrici, zbrojimo cijelu stvar i dobijemo rezultirajuću sliku.

U ovom trenutku više ne radimo u prostorima boja, već izravno s G matricom (bazni ponderi), sve daljnje komprimiranje vrši se izravno na ovoj matrici.

Međutim, ovdje je problem taj što smo sada pretvorili bajtno usklađene cjelobrojne vrijednosti u stvarne brojeve. Što učinkovito nadoknađuje naše podatke (pomicanje s 1 bajta na 1 plutajući (4 bajta)). Da bismo to riješili i počeli proizvoditi značajniju kompresiju, prelazimo u fazu kvantizacije.

Kvantizacija

Dakle, ne želimo komprimirati podatke s pokretnom zarezom. To bi napuhalo naš tok i ne bi bilo učinkovito. U tu svrhu željeli bismo pronaći način za pretvaranje matrice pondera natrag u vrijednosti u prostoru [0,255]. Izravno bismo to mogli učiniti pronalaženjem min / max vrijednosti za matricu (-415,38, odnosno 77,13) i dijeljenjem svakog broja u ovom rasponu kako bismo dobili vrijednost između [0,1] na koju množimo sa 255 da dobijemo našu konačnu vrijednost.

Na primjer: [34,12- -415,38] / [77,13 - -415,38] * 255 = 232

To djeluje, ali kompromis je značajno smanjenje preciznosti. Ovo skaliranje proizvest će neravnomjernu raspodjelu vrijednosti, što rezultira značajnim vizualnim gubitkom slike.

Umjesto toga, JPG ide drugim putem. Umjesto da koristi raspon vrijednosti u matrici kao vrijednost skaliranja, on umjesto toga koristi unaprijed izračunatu matricu faktora kvantizacije. Ovi QF-ovi ne trebaju biti dio toka, već mogu biti dio samog kodeka.

Ovaj primjer prikazuje uobičajenu matricu faktora kvantizacije, po jednu za svaku osnovnu sliku,

Sada koristimo Q i G matrice za izračunavanje naše kvantizirane matrice DCT koeficijenta:

Na primjer, koristeći vrijednosti G [0,0] = - 415,37 i Q [0,0] = 16:

Rezultat je konačna matrica od:

Promatrajte koliko matrica postaje jednostavnija - ona sad sadrži velik broj unosa koji su mali ili nula, što ju čini mnogo lakšom za sažimanje.

Kao brzinu, ovaj postupak primjenjujemo na Y, CbCr kanale neovisno i kao takve trebamo dvije različite matrice: jednu za Y, a drugu za C kanale:

Kvantizacija komprimira sliku na dva važna načina: jedan ograničava efektivni raspon težina, smanjujući broj bitova potrebnih za njihovo predstavljanje. Drugo, mnogi utezi postaju identični ili nula, poboljšavajući kompresiju u trećem koraku, kodiranje entropije.

Kako je takva kvantizacija primarni izvor JPEG artefakata. Budući da slike u donjem desnom dijelu imaju najveće djelitelje kvantizacije, JPEG artefakti skloni su sličnosti kombinacija tih slika. Matricom faktora kvantizacije može se izravno upravljati mijenjanjem JPEG-ove "razine kvalitete", koja svoje vrijednosti skalira prema gore ili prema dolje (to ćemo pokriti za minutu)

Kompresija

Do sada smo se vratili u svijet cjelobrojnih vrijednosti i možemo krenuti naprijed primjenom stupnja kompresije bez gubitaka na naše blokove. Ipak, gledajući naše transformirane podatke, trebali biste primijetiti nešto zanimljivo:

Kako se krećete od gornjeg lijevog do donjeg desnog dijela, učestalost nula se povećava. Ovo izgleda kao glavni osumnjičenik za kodiranje dužine izvođenja. No, redovi velikih i glavnih stupaca ovdje nisu idealni, jer bi to prepletalo te nule, umjesto da ih sve spakira.

Umjesto toga, započinjemo s gornjim lijevim kutom i cik-cak u dijagonalnom uzorku preko matrice, idući naprijed-nazad dok ne dođemo do donjeg desnog kuta.

Rezultat naše luma matrice, ovim redoslijedom, postaje:

−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,0

Jednom kada su podaci u ovom formatu, sljedeći su koraci jednostavni: izvršite RLE na sekvenci, a zatim na rezultate primijenite neki statistički koder (Huffman / Arithmetic / ANS).

I Bum. Vaš blok je sada JPG kodiran.

Razumijevanje parametra kvalitete

Sad kad ste shvatili kako zapravo nastaju JPG datoteke, vrijedi ponovno posjetiti koncept parametra kvalitete koji obično vidite prilikom izvoza JPG slika iz Photoshopa (ili što već).

Ovaj parametar, koji ćemo nazvati q, cijeli je broj od 1 do 100. O q biste trebali razmišljati kao o mjerilu kvalitete slike: veće vrijednosti q odgovaraju slikama veće kvalitete i većim veličinama datoteka.

Ova vrijednost kvalitete koristi se tijekom faze kvantiziranja za odgovarajuće skaliranje čimbenika kvantiziranja. Tako da po osnovnoj težini, korak kvantizacije sada sliči okruglom (Gi, k / alpha * Qi, k)

Gdje je alfa simbol stvoren kao rezultat parametra kvalitete.

Kada se poveća ili alfa ili Q [x, y] (imajte na umu da velike vrijednosti alfa odgovaraju manjim vrijednostima parametra kvalitete q), gubi se više podataka i veličina datoteke se smanjuje .

Kao takvi, ako želite manju datoteku, po cijenu više vizualnih artefakata, možete postaviti nižu vrijednost kvalitete tijekom faze izvoza.

Gore primijetite, na najnižoj kvaliteti slike, kako vidimo jasne znakove stupnja blokiranja, kao i stupnja kvantizacije.

Vjerojatno najvažnije je da parametar kvalitete varira ovisno o slici . Budući da je svaka slika jedinstvena i prikazuje različite vrste vizualnih artefakata, vrijednost Q također će biti jedinstvena.

Zaključak

Jednom kad shvatite kako funkcionira JPG algoritam, postaje očito nekoliko stvari:

  1. Ispravno utvrđivanje vrijednosti kvalitete po slici važno je kako bi se pronašao kompromis između vizualne kvalitete i veličine datoteke.
  2. Budući da se ovaj proces temelji na blokovima, artefakti će se obično pojavljivati ​​u blokadi ili "zvonu"
  3. Budući da se obrađeni blokovi međusobno ne miješaju, JPG uglavnom zanemaruje mogućnost komprimiranja velikih dijelova sličnih blokova. Rješavanje te zabrinutosti nešto je što WebP format dobro radi.

A ako se želite sami poigrati sa svime tim, sve se to ludilo može svesti na datoteku od ~ 1000 redaka.

HEJ!

Želite znati kako svoje JPG datoteke smanjiti?

Želite znati kako rade PNG datoteke ili kako ih učiniti manjim?

Želite više kompresije podataka dobrote? Kupi moju knjigu!