
Hogyan működik a JPG
A JPG fájlformátum a képtömörítés egyik leglényegesebb előrelépése volt, amely 1992-ben jelent meg a színen. Azóta meghatározó erő a fényképminőségű képek megjelenítésében az interneten. És jó okkal. A JPG működésének hátterében álló technológia nagy része rendkívül összetett, és megköveteli annak szilárd megértését, hogy az emberi szem hogyan alkalmazkodik a színek és élek érzékeléséhez.
És mivel ilyen dolgokkal foglalkozom (és te is, ha ezt olvasod), szerettem volna lebontani a JPG kódolás működését, hogy jobban megértsük, hogyan lehet kisebb JPG fájlokat készíteni.
A LÉNYEG
A JPG tömörítési sémát több szakaszra bontják. Az alábbi kép magas szinten leírja őket, és végig fogjuk járni az egyes fázisokat.

Színtér átalakítása
A veszteséges adattömörítés egyik alapelve , hogy az emberi érzékelők nem annyira pontosak, mint a számítási rendszerek. Tudományosan az emberi szem csak fizikai képességgel rendelkezik ahhoz, hogy körülbelül 10 millió különböző színt megkülönböztessen. Számos dolog befolyásolhatja azonban, hogy az emberi szem hogyan érzékeli a színt; tökéletesen kiemelve színes illúziókkal, vagy azzal a ténnyel, hogy ez a ruha feltörte az internetet. A lényeg az, hogy az emberi szem szépen manipulálható az általa érzékelt színek tekintetében.
A kvantálás ennek a hatásnak a formája a veszteséges képtömörítésben, azonban a JPG ehhez más megközelítést alkalmaz: színes modellek . A színtér a színek sajátos szervezete, és színmodellje a matematikai képletet képviseli a színek megjelenítésének módjára (pl. Hármasok RGB-ben vagy négyszeresek a CMYK-ban).
A leghatékonyabb ebben a folyamatban az, hogy konvertálhat egyik színmodellről a másikra , vagyis megváltoztathatja az adott szín matematikai ábrázolását, teljesen más numerikus értékkészlettel.
Például az alábbiakban egy adott szín látható, és az ábrázolása RGB és CMYK színmodellekben azonos színű az emberi szem számára, de más numerikus értékkészlettel ábrázolható.

A JPG RGB-ből Y, Cb, Cr színmodellt alakít át; Amely tartalmaz fényerőt (Y), krómkéket (Cb) és krómvöröset (Cr). Ennek az az oka, hogy a pszicho-vizuális kísérletek (más néven az agy működése a szem látott információival) azt mutatják, hogy az emberi szem érzékenyebb a fényerőre, mint a színárnyalatra, ami azt jelenti, hogy elhanyagolhatjuk a krominancia nagyobb változásait anélkül, hogy befolyásolnánk a kép észlelése. Mint ilyen, agresszív változásokat hajthatunk végre a CbCr csatornákon, mielőtt az emberi szem észrevenné.

Alulmintavétel
Az YCbCr színtér egyik érdekes eredménye, hogy az eredményül kapott Cb / Cr csatornák kevésbé finom részletek; kevesebb információt tartalmaznak, mint az Y csatorna.
Ennek eredményeként a JPG algoritmus átméretezi a Cb és Cr csatornákat körülbelül eredeti méretükhöz (megjegyezzük, van némi árnyalat ennek a megvalósításában, amelyet itt nem fedek le ...), amelyet downsample-nek hívnak .
Ami itt fontos megjegyezni, hogy az almintavétel veszteséges tömörítési folyamat (a pontos forrásszínek nem lesznek helyreállíthatók, csak szorosan közelítjük meg), de az emberi vizuális kéreg vizuális összetevőire gyakorolt összhatása minimális. Luma (Y) az érdekes dolgok, és mivel csak a CbCr csatornákat választjuk le, ezért a vizuális rendszerre gyakorolt hatás csekély.

Kép 8x8 pixel blokkokra osztva
Innentől kezdve a JPG minden műveletet 8x8 pixeles blokkon végez. Ez azért történik, mert általában arra számítunk, hogy a 8x8 blokkok között nincs sok eltérés, még a nagyon összetett fotóknál is előfordul némi önhasonlat a helyi területeken; ezt a hasonlóságot használjuk ki később a tömörítés során.
Érdemes megjegyezni, hogy ezen a ponton bemutatjuk a JPG kódolás egyik első gyakori „műtermékét”. A „színes vérzés” az éles szélek mentén lévő színek „vérzése” a másik oldalon. Ennek oka, hogy a pixelek színét kifejező krominancia csatornák mindegyik 4 pixeles blokkját átlagolták egy színre, és ezek közül a blokkok közül néhány átmegy az éles élen.
Diszkrét koszinusz-transzformáció
Egészen idáig a dolgok elég szelídek voltak. A színtér, a mintavétel és a blokkolás egyszerű dolog a képtömörítés világában. De most ... most megjelenik az igazi matematika.
A DCT transzformáció kulcsfontosságú eleme, hogy feltételezi, hogy bármely numerikus jel újra létrehozható a koszinusz-funkciók kombinációjával.
Például, ha ez a grafikon van az alábbiakban:

Láthatja, hogy valójában cos (x) + cos (2x) + cos (4x) összege

Talán ennek jobb megjelenítése a kép tényleges dekódolása, adott koszinusz-funkciók sorozata egy 2D-s térben. Ennek bemutatásához bemutatom az internet egyik legcsodálatosabb GIF-jét: egy 8x8 pixeles blokk kódolása koszinuszok használatával 2D-s térben:

Amit itt néz, az egy kép rekonstrukciója (bal szélső panel). Minden képkockából új alapértéket veszünk fel (jobb oldali panel), és megszorozzuk egy súlyértékkel (jobb oldali panel szövege), hogy előállítsuk a képhez való hozzájárulást (középső panel).
Amint láthatja, a különféle koszinusz-értékeket egy súlyhoz viszonyítva rekonstruálhatjuk eredeti képünket (elég jól ...)
Ez az alapvető háttér a diszkrét koszinusz-transzformáció működéséhez. Az ötlet az, hogy bármely 8x8 blokk súlyozott koszinusz-transzformációk összegeként jeleníthető meg, különböző frekvenciákon. A trükk ebben az egészben az, hogy kitaláljuk, milyen koszinusz-bemeneteket használjunk, és hogyan kell őket súlyozni.
Kiderült, hogy a „ milyen koszinuszokat használni” probléma meglehetősen egyszerű; Sok tesztelés után a koszinusz-értékek halmazát választották a legjobb eredmény elérése érdekében, ezek az alapfunkcióink, és az alábbi képen láthatóak.

Ami a „hogyan kell súlyozni őket együtt” problémáig egyszerűen (HA!) Alkalmazza ezt a képletet.

Megkíméllek, mit jelent mindez az érték, megnézheti őket a wikipédia oldalon.
Az alapvető eredmény az, hogy minden színcsatornában egy 8x8 pixelblokk esetében a fenti képlet és bázisfüggvények alkalmazásával egy új 8x8 mátrix jön létre, amely a rekonstrukció során használandó súlyokat képviseli. Itt van egy ábra a folyamatról:

Ez a G mátrix képviseli a kép rekonstrukciójához használt alapsúlyokat (a fenti animáció jobb alsó sarkában található kis tizedesérték). Alapvetően minden egyes alapra megszorozzuk a mátrix súlyával, összeadjuk az egészet, és megkapjuk a kapott képet.
Ezen a ponton már nem színes terekben dolgozunk, hanem közvetlenül a G mátrixszal (alapsúlyokkal), minden további tömörítést közvetlenül ezen a mátrixon hajtunk végre.
A probléma itt az, hogy most a bájtokkal igazított egész számokat valós számokká alakítottuk át. Ami hatékonyan felfújja az információinkat (1 bájtról 1 úszóra (4 bájt) haladva). Ennek megoldása és a jelentősebb tömörítés megkezdése érdekében a kvantálási szakaszba lépünk.
Kvantálás
Tehát nem akarjuk a lebegőpontos adatokat tömöríteni. Ez felfújná az adatfolyamunkat, és nem lenne hatékony. Ebből a célból szeretnénk megtalálni a módot arra, hogy a súlymátrixot visszaállítsuk értékekké a [0,255] térben. Közvetlenül ezt megtehetnénk úgy, hogy megtaláljuk a mátrix min / max értékét (-415,38, illetve 77,13), és elosztjuk ebben a tartományban az egyes számokat, így kapunk egy értéket [0,1] között, amelyhez 255-tel szorozzuk. hogy megkapjuk a végső értékünket.
Például: [34,12–415,38] / [77,13–415,38] * 255 = 232
Ez működik, de a kompromisszum jelentős pontosságcsökkenést jelent. Ez a méretezés az értékek egyenetlen eloszlását eredményezi, amelynek eredményeként a kép jelentős vizuális veszteséget okoz.
Ehelyett a JPG más utat választ. Ahelyett, hogy az értéktartományt a mátrixban méretezési értékként használja, ehelyett a kvantálási tényezők előre kiszámított mátrixát használja. Ezeknek a QF-eknek nem feltétlenül kell a stream részeinek lenniük, inkább maguknak a kodeknek lehetnek részei.
Ez a példa a kvantálási tényezők általánosan használt mátrixát mutatja, mindegyik alapképhez egyet,

Most a Q és G mátrixokat használjuk a kvantált DCT együttható mátrix kiszámításához:

Például a G [0,0] = - 415,37 és Q [0,0] = 16 értékeket használva:

Eredmény a végső mátrixban:

Figyelje meg, mennyivel egyszerűbbé válik a mátrix - ez most nagyszámú, kicsi vagy nulla bejegyzést tartalmaz, így sokkal könnyebben tömöríthető.
Gyors eltekintésként ezt a folyamatot függetlenül alkalmazzuk az Y, a CbCr csatornákra, és ezért két különböző mátrixra van szükségünk: az egyik az Y-re, a másik a C-csatornákra:


A kvantálás két fontos módon tömöríti a képet: az egyik, korlátozza a súlyok tényleges tartományát, csökkentve az ábrázolásukhoz szükséges bitek számát. Kettő, sok súly megegyezik vagy nulla lesz, javítva a tömörítést a harmadik lépésben, az entrópia kódolásával.
Mivel a kvantálás a JPEG-artefaktusok elsődleges forrása. Mivel a jobb alsó sarokban lévő képek általában a legnagyobb kvantálási osztókkal rendelkeznek, a JPEG-artefaktumok általában hasonlítanak e képek kombinációira. A kvantálási tényezők mátrixa közvetlenül szabályozható a JPEG „minőségi szintjének” megváltoztatásával, amely felfelé vagy lefelé skálázza az értékeit (ezt egy perc alatt lefedjük)
Tömörítés
Mostanra visszatértünk az egész értékek világába, és előre léphetünk, ha veszteségmentes tömörítési fokozatot alkalmazunk blokkjainkra. Ha azonban az átalakított adatainkat nézi, észre kell vennie valami érdekeset:

A bal felső saroktól a jobb alsó részig haladva a nullák gyakorisága növekszik. Ez úgy tűnik, mint a Run Length Encoding elsődleges gyanúsítottja. De a sor-fő és az oszlop-fő megrendelések itt nem ideálisak, mivel ez összevonja ezeket a nulla meneteket, ahelyett, hogy mindet összecsomagolná.
Ehelyett a bal felső sarokkal kezdjük, és a mátrixon átlós mintázatban cikk-cakkban kezdünk előre-hátra, amíg el nem érjük a jobb alsó sarkot.

A luma mátrixunk eredménye ebben a sorrendben:
−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,0,0,0,0
Miután az adatok ebben a formátumban vannak, a következő lépések egyszerűek: hajtsa végre az RLE-t a szekvencián, majd alkalmazzon valamilyen statisztikai kódolót (Huffman / Arithmetic / ANS) az eredményekre.
És Boom. A blokkod most JPG kódolású.
A minőségi paraméter megértése
Most, hogy megértette a JPG fájlok tényleges létrehozását, érdemes felülvizsgálni a minőségi paraméter fogalmát , amelyet általában a JPG képek Photoshopból (vagy mi másból) történő exportálásakor lát.
Ez a paraméter, amelyet q-nak hívunk, 1 és 100 közötti egész szám. A q-ról úgy kell gondolkodni, mint a kép minőségének mértékéről: a q magasabb értékei megfelelnek a jobb minőségű képeknek és a nagyobb fájlméreteknek.
Ezt a minőségi értéket a kvantálási szakaszban használják a kvantálási tényezők megfelelő méretezéséhez. Tehát, hogy alaptömegenként a kvantálási lépés most a kerekre hasonlít (Gi, k / alfa * Qi, k)
Ahol az alfa szimbólum a minőségi paraméter eredményeként jön létre.

Ha az alfa vagy a Q [x, y] értéke megnövekszik (ne feledje, hogy az alfa nagy értékei megfelelnek a q minőségi paraméter kisebb értékeinek), akkor több információ veszít el, és a fájl mérete csökken .
Mint ilyen, ha kisebb fájlt szeretne, több vizuális műtárgy árán, alacsonyabb minőségi értéket állíthat be az exportálási szakaszban.

Fentebb vegye figyelembe, hogy a legalacsonyabb minőségű képen hogyan látjuk a blokkolási szakasz és a kvantálási szakasz egyértelmű jeleit.
Valószínűleg az a legfontosabb, hogy a minőségi paraméter a képtől függően változik . Mivel minden kép egyedi, és különböző típusú vizuális tárgyakat mutat be, a Q értéke is egyedi lesz.
Következtetés
Miután megértette a JPG algoritmus működését, néhány dolog nyilvánvalóvá válik:
- A képi minőség megfelelő értékének megadása fontos a vizuális minőség és a fájlméret közötti kompromisszum megtalálásához.
- Mivel ez a folyamat blokk alapú, az artefaktumok általában blokkolásban vagy „csengésben” fordulnak elő
- Mivel a feldolgozott blokkok nem keverednek egymással, a JPG általában figyelmen kívül hagyja a hasonló blokkok nagy csoportjainak tömörítését. Ennek az aggodalomnak a megválaszolására a WebP formátum alkalmas.
És ha egyedül akar játszani mindezzel, akkor ezt az őrületet ~ 1000 soros állománygá lehet forralni.
HÉ!
Szeretné tudni, hogyan lehet kisebb JPG fájlokat?
Szeretné tudni, hogyan működnek a PNG fájlok, vagy hogyan lehet kisebbé tenni őket?
Szeretne még több adattömörítési jóságot? Vedd meg a könyvemet!