2017. okt. 17.

JPEG összefoglaló 7

A minap abbahagyott gondolatsort folytatjuk.

4. Melyik a jobb, vagy ugyanolyan a Save as 12-es szint és a Save for Web 100%? Ez se egy érvényes kérdés, mert aki ennyire szőrszálhasogató, az mentsen TIFF-et LZW tömörítéssel, az Isten szerelmére. De nem egyformák. A JPEGSnoop szerint 3 század százalék eltérés van a kettő között. Borzi. Tehát a Save for Web 100% a legbesztesebb, 98,39-es minőség faktorral, míg a Save As 12, 98,36-os faktorral alig rosszabb a kroma csatornákon. A luminancia csatornákon is 6 századnyi csupán az eltérés. A Nikon D5000 Fine beállítás a kroma csatornán ugyanolyan jó (de nem azonos kvantálású + ne feledjük a subsamplinget se) mint a Save for Webb 100%, luminancia csatornája viszont csak 98,02-es. 

5. Miért van a PS-ban 13 tömörítési szint? És a PS alapesetben miért csak a 10-es értéket ajánlja fel? Sajnos hivatalosnak tűnő válaszokat nem találtunk, tehát anekdotikusnak kell tekintenünk őket. A 11-12-es értékek állítólag a fejlesztés korából maradtak benne, bármit is jelentsen ez. A PS szerint a kiváló minőséget már a 10-es garantálja. Mint a 4-es pontból láttuk, ez egyáltalán nincs így. Úgy tűnik, hogy az Adobe sem veszi komolyan a JPEG-et. Nincs mese, a JPEG mintha csak végfelhasználásra lenne szánva. Ha így tekintünk erre a formátumra, akkor már a 8-as minőség is tökéletesen megfelel internetre. A 12-es érték ára nagyjából dupla fileméret (a 10-eshez képest - lásd alább).
Lehet találgatni, melyik a 10-es és melyik a 12-es. 
6. Mi történik a PS-ban a 6-os illetve a 7-es beállítások között?
Valószínű, hogy nektek se tűnt föl eddig, hogy a 6-7-es értékeknél Photoshopban valami gubanc van. Pedig az internet tele van magyarázatokkal. Ha eddig ezeket az értékeket használtad, akkor érdemes megfigyelni azt a jelenséget, hogy az elvárttal ellentétben a 7-es értékkel, a 6-oshoz viszonyítva, nem nagyobb lesz a fileméret, hanem kisebb (lásd alább az ábrán). A képminőség sem lesz egyértelműen jobb, inkább másképp lesz szarabb.
Megkattintva nézd, 300% nagyítás. Balról és fentről 0-12 JPG tömörítés PS-ban.
 A PS 13 értékének hatása a fileméretre. Érdemes figyelni a 6-7 értékekre,
illetve a 11-12 értékekre.
Gyakorlatilag 0-6 szintek között a kroma subsampling 2x2 (negyedére csökken a CrCb felbontása), míg a 7-12 között a kroma subsampling:  1x1. Emiatt 7-esnél nagyobb ugrás lenne tapasztalható a fileméretben, ezt mérséklendő, itt nagyobb kvantálási értékeket alkalmaznak. Képe válogatja, hogy ezzel a trükkel mennyire sikerül a fileméretet a 6-os és 8-as fileméretei közé szorítani. A mi példánkban nem sikerült. 6-os értékkel 1536 kbyte, 7-es értékkel pedig 1532 kbyte lett az eredmény. Alább a 6-os és 7-es kvantálási táblái:



Mivel a luminancia tábláját is jól megtömöríti (a 6-os tömörítéshez képest), simán előfordulhat, hogy gyengébb képet kapunk a jobb beállítás mellett, nagyobb színfelbontással.

+ Bónuszprogram. A JPEGmini szolgáltatása. 
Többet vártam tőle, abból ahogyan feldicsérték valamelyik blogon. Sajnos csak JPEG képeket fogad, adta magát a kísérlet, hogy sorra odaadjuk neki a 0-12 értéken tömörített fájlokat, lám mit kezd velük. Ezeket azután fileméret szerint megfeleltettük a PS-ban tömörített állományokkal. Nagyjából egy értékkel tömörítette be jobban, tehát a 12-esből a mini kb. 10-11 közöttinek megfelelő méretűt produkált. A 10-esből 9-est, 6-osból meg 5-öst. A képeket összevillogtatva (400%) a mérettel nagyjából arányos volt a minőség is, bár a 12-10-es tömörítéseknél megoszlott a véleményünk, volt aki a nagyobb mini képet tartotta jobbnak, én pedig inkább a picivel kisebb PS képet. A különbség egyáltalán nem mérvadó. Mindenesetre kijelenthető, hogy a JPEG mini nem csodaszer, nyugodtan hanyagolhatjátok. 

2017. okt. 16.

Melyik formátum mekkora fileméretet okoz?

Az  Utazások egészen parányi blog ahhoz, hogy nagy kísérleteket lefolytassunk. A következő cuccot is sok-sok képpel kelletett volna megcsinálni és különböző fotó-témák szerint statisztikákat felállítani, hogy egy precíz eredményt kapjunk. De mi most egyetlen képpel csináljuk meg. Van rajta jó nagy ég, szikla, meg fák, tipikus hegyi tájkép. Ilyenből készítünk a legtöbbet, szóval az, amit ebből megállapítunk, jó lesz nekünk az elkövetkezőkre.






Minden formátumnál a maximálisan elérhető minőséget állítottuk be, akár a gyorsaság rovására is. A lassú mentés leginkább a tömörített TIFF-ekre (főleg a ZIP), JP2000-re illetve a PNG-re volt jellemző.
8 bites formátumok

16 bites formátumok
8 biten egyértelműen a SOOC-hívők járnak a legjobban tárhely szempontjából. A D5000 color subsamplinget is használ, és sokkal durvábban tömörít, mint a PS maximum minősége. 
Továbbá az derül ki, hogy még mindig a legjobb megoldás a nyers file tárolása. Leginkább DNG formátumban. (gyanítjuk, hogy a demosaic előtti állapot miatt harmadannyi adatot tárol, illetve JPEG previewt sem tartalmaz). Mivel open-source, remélhetőleg 10-15 év múlva sem ér majd meglepetés minket, bár azért annyira nem bíznék meg benne, mint a JPEG-ben.

Van egy olyan tévhit, hogy a DNG kevesebb, vagy másabb, mint az eredeti RAW. Tesztjeink ezt nem támasztották alá, a NEF, illetve DNG, Camera RAW-ból nyitva, difference összhatásra semmilyen különbséget nem mutat ki.

Amennyiben PS-ban piszkálni kell a képet, a JP2000 veszteségmentes tömörítése adja a legkisebb méretet, de 16 biten ez így is majdnem ötszöröse a DNG-nek. 8 bitesen csupán másfélszerese. Egy TIFF-el összehasonlítva semmilyen különbség nem mutatható ki, tehát teljesen veszteségmentesnek tekinthető. Sajnos a JP2000-nek nem sikerült annyira elterjedni, mint a JPEG-nek. Pl. a blogger sem fogad JPF-et.

Ha rétegeink is vannak, akkor 8 biten a TIFF LZV a jobb, 16 biten viszont vállalhatatlanul elrontottak valamit, mert kiemelkedően rosszabb, mint a nem tömörített változat. A TIFF ZIP jó megoldásnak tűnik, kevés kép esetén nem zavaró a lassúsága, viszont nincs nagyon elterjedve, nem minden szoftver lesz képes megpiszkálni. Na így.

2017. okt. 12.

Ringasd el magad - hánytató képek

Bár az internet nagyobb hájpjai nem kímélnek minket sem, azért számunkra is létezik újdonság, a fejrázogatós optikai illúzió például eddig elkerült. Elkészíteni viszont egyszerű, egy fekete-fehér (függőleges) rács alá kell behelyezni a megjelenítendő fekete-fehér ábrát, de csak 10-20% átlátszósággal, éppen csak, hogy ne lehessen észrevenni fejrázogatás nélkül. 

A fekete-fehér vonalak fejrázogatás közben aztán szépen szürkévé olvadnak és felsejlik az alárejtett ábra is. Kipróbáltuk a fekete vonalakba rejtve is, de úgy nem működött. Viszont fehér-szürke rácsokkal is jó. És nem feltétlenül kell rázogatni a fejet, kellő nagy távolságból szemlélve, szintén felsejlik a rejtett kép. De működik például piros-cián párosban is. 
Érdemes már az elején eldönteni a végleges méretet, mert rosszul viseli a skálázást, ugyanis az élek kontrasztosak kell legyenek, a közök meg egyformák. Érdemes figyelembe venni a megjelenítő monitor felbontását/méretét is, mert pl. egy sűrűbb felbontású monitoron anélkül is összeolvadnak a komplementer vonalak, hogy rázogatnánk a fejünket. Például a félhádés monitoron szerkesztett képek a kétkás monitoron teljesen használhatatlanok. Ha tehát már fejrázogatás nélkül is látsz valamit a csíkokban, akkor érdemes egészen közel menni a monitorhoz.
Pulsz egy másik érdekesség, ha 30 másodpercig bámulod a csíkokat mereven, majd lenézel a billentyűzetre, az is jó tud lenni :)
Na, ezzel is el lehet cseszni egy délutánt. 

2017. okt. 10.

JPEG APP Markerek - egyszerű (tökéletlen) csináld-magad vízjel

Amelyben kicsit felmelegítjük a sztegano és watermark témát kifejezetten a JPEG-ről tanultakat felhasználva. Amúgy közben találtunk egy régi könyvet, amiben mindenféle fileokban és mindenféle módokon  dugdosnak el titkos tartalmakat. Ide linkelem

Minden JPEG két marker, a 0xFFD8 és 0xFFD9 között helyezkedik el. Ezek a StartOfImage illetve EndOfImage speciális markerek, ugyanis nem következik utánuk adat.
Mivel a 0xFFD9 után a szoftverek már nem értelmezik a képet, ezért adja magát a lehetőség, hogy ide is rejthetünk tartalmat (hasonlóképpen, mint azt a BMP esetén már csináltuk). Gyakorlatilag a JPEG után szúrjuk be a cuccot.
Természetesen Szilágyit dugtuk el a file végén
Sajni, ezzel az a probléma, hogy újramentve PS-ben, törlődik minden, ami a  0xFFD9 marker után áll. Tehát nem bírja a szerkesztést. Kipróbáltuk, hátha a bele rejtett szöveg utáni  újabb 0xFFD9 megoldja a problémát, de nem. És persze nem lepett meg, hogy a Facebook se hagyta nyitva ezt a kiskaput. De a Google például igen (a BMP módszer pl. náluk nem működött). Később találtunk egy cikket, ahol egy JPEG-be rejtett ZIP állományt találnak meg azzal a módszerrel, hogy simán rákeresnek az EOI markerre. Na jó, köszi, ezek után semmibe nem kerül egy robottal figyeltetni hány EOI van egy JPEG-ben. Ennél valamivel combosabb megoldás kellene, ha legalább a Facebook beszopná, lehetne használni watermarknak (steganora semmiképp, még kriptálva is csak a szomszéd ellen), de így nem éri meg monyolni vele. 

Általában a JPEG többi markerei így néznek ki:
0xFF+Marker Number(1 byte)+Data size(2 bytes)+Data(n bytes)
0xFFE0-0xFFEF, vagyis az Application Markerek (összesen 16) nem szükségesek a JPEG kikódolására, ide írhatnak a szoftverek. Például az EXIF-et (amire remélem majd egyszer visszatérünk), ami történetesen az APP1(0xFFE1) markert használja. Az EXIF tagokról ez is érdekes olvasmány. Mindenesetre az EXIF-et nem tartjuk érdemesnek titkolt vízjel elhelyezésére, ugyanis könnyen törölhető. EXIF-ben érdemes ugyan copyright infókat tárolni, mivel még a Facebook is megtartja, de ha titkosat akarunk, akkor nem ez a megoldás.

Az 0xFFEC  marker, vagyis az APP12 "Ducky" marker elárulja, hogy a képünk Save for Web 60% beállítással volt mentve:
A marker utáni két byte: 0x0011 - 17 byte adatot jelent, de ebbe a Data Size is beleértendő, tehát még 15 byte adatnak jut hely a következő markerig (0xFFE1). Ebből a 0x003C jelenti a 60%-os tömörítést, amit a PS olt bele a fileba, ha Save for Web parancsot használunk.
Ha viszont Save as-t használtunk akkor az 0xFFED markerben (APP13) a 0x0406 Photoshop IRB resource pont (JPEG quality-t jelöli) után írja be a mentési minőséget. A 0x0008 az 12-es mentési minőséget jelenti. Részletesebben, itt arról, hogy milyen érték mit jelent.
Na jó, egy másik ötletünk az volt, hogy keressünk egy olyan markert, amit nem listáz az EXIFTOOLS sem, ahova írhatnánk saját infókat. Mivel az APP12 (Ducky marker) a SaveForWeb esetén kap értéket, nem is volt jelen a kiindulási fileban. 
Az 0xFFED elé szúrtuk be tehát, 0xFFEC címen (APP12) 0x000E hosszon (12byte), azt, hogy "krikszkraksz". Az ExifTools nem mutatja ki, de sajnos ez is törölhető a full metaadat törléssel. A Photoshop még úgy is felülírja mentéskor, hogyha nem a Save for Web parancsot használjuk. Ezután az APP14 marker tűnt jó választásnak, mivel tartalmazhat olyan információkat, amelyek érinthetik a kép megjelenítését. Ezért az ExifTools sem törli, legalábbis egy fórum szerint, ahol maga Phil Harvey írja ezt. 
Sajnos de. Azóta megváltozhatott a dolog. Valahogyan csak visszaállítja az eredeti értéket. A PS meg pláne minden mentésnél átírja.
Ugyanez volt az APP7-11 esetén is, pedig itt kifejezetten olyan markerek vannak, amiket nem a PS használ. De törli az ide rejtett információkat a Facebook is. Szóval az APP markerek úgy tűnik egyáltalán nem jó megoldás szteganográfiára.

Az a gyanúnk, hogy jól ki van találva ez a JPEG szabvány és eléggé le vannak zárva benne a kiskapuk. Korábban kellene kelni ahhoz, hogy meghekkeljük. 

2017. okt. 9.

Color-lateral damage

A JPEG kapcsán felmerülő veszteségmentes/veszteséges színtér konverzió mentén próbálunk meg kísérletezgetni. Vizsgáljuk, hogy a színtérváltásának lehet  e vesztesége, aztán a színprofil váltások és a színmélység csereberéje is sorra kerül.
Forrás
A színtérváltás valószínűleg rossz. Alapesetben készítünk egy RAW-ot, amihez AdobeCameraRAW-ban kamera profilt rendelünk. Ebből következik egy, optimális esetben veszteségmentes maszter-kép aRGB profillal (16 biten). Ezután, amennyiben netre szánjuk a képet, történik egy sRGB átalakítás. Mint már említettük, pl. RGB-ben nem lehet hatékonyan tömöríteni. Ezért van egy YCbCr átalakítás is, majd megnyitásnál újra vissza RGB-be. De konkrétan milyen veszteségekkel járhat ez? 

A legutolsó színmód váltást nem tudjuk konkrétan ellenőrizni, ugyanis a PS nem tud YCbCr módba alakítani, csak elvégzi a háttérben a JPEG kódolása során.  De mivel a JPEG amúgy is veszteséges, egy egyszerű mentéssel semmi nem fog kiderülni a színmód váltással okozott veszteségekről.
Lab módban próbáljuk tehát szimulálni a dolgot. A képet átkonvertáljuk, majd vissza, és egy differencies szűrővel az eredetire szűrjük. Érdemes egy kontrasztgörbét is nekitámasztani, aztán ha van latens különbség, akkor az is megjelenik íziben. Vagy easyben. Ilyen játékok következnek.

Lássuk az RGB - Lab - RGB konverziót. Kezdjük 16 biten.

A képernyőkép mutatja, hogy az eltérések csupán a sötét tónusok legeslegvégén (baloldalt egy vékony sávban) jelentkeznek. Ez az eltérés maga a konverzióból származó veszteség. Értéke 1-2%, nem észlelhető mindaddig, amíg nagyon durva kontrasztgörbével (gyakorlatilag falig tolva: input 4, output 255) fel nem erősítjük. 

A világos zöld színeket érinti a veszteség, ott is elszigetelten pixelcsoportokra (lásd a nagyított részletet), és leginkább csak a kék csatornára korlátozódik, egy kevés pirossal fűszerezve. Hát ez nagyon mutatja, hogy a Lab pont a zöld színekben bővebb, mint az RGB. A 8 bites kép viszont már igencsak szürreális. Szinte önmagában egy műalkotás. Érinti ez a teljes képet, égszínkéket, sötétzöldet, mindent. Itt már nem elszigetelt pixelcsoportokról beszélünk, valójában csak elszigetelt pixelek maradnak ki a veszteségből. Itt is dominánsan a kék csatorna veszít a legtöbbet, de azért van bőven a piros és zöld pixelben is veszteség.

Bár az átalakítás hatása a valóságban nem ennyire hangsúlyos, ugyanis erős kontrasztolással tettük egyáltalán láthatóvá, azért a jelenség létezik. És a tanulság is egyértelmű. Ha színtereket kell csereberélni, akkor csakis 16 bit.

Ha már így nekifogtunk, akkor az sRGB - adobeRGB átalakítást is leteszteljük. Oda-vissza. Értelmezze mindenki, ahogyan csak szeretné.

Azt is leellenőriztük, hogy önmagában a 16-8-16 bites átalakítások eltérése egy teljesen sztohasztikus zajt eredményezett, semmiféle relációt nem mutatva a kép elemeihez viszonyítva. Gyanítjuk, hogy a pixelek átszámolása során a kerekítések a hibások.

Körkérdés mindenkihez: De mi lehet a JPEG mentése során bekövetkező színtérváltásnál? A webdesignerdepot azt állítja, hogy a színtér-konverzió 16 millió bemeneti színből csupán 4 milliót képes visszahozni, egyszeri alkalommal fordul elő (nem okoz generációs veszteség-felhalmozódást- ezzel nem értünk egyet).
 Az RGB - YCbCr konverzió lényege itt olvasható. Az ImpulseAdventure a matematika felől közelíti meg a színtércsere veszteségeit, azt állítva, hogy pl. az Y kiszámolásában a szorzások részeredményeit egyenként kerekítik (gyakorlatilag trimmelik a törtrészt). Pl. egy R132 G132 B132 pixel esetén:
Y=0.299*132 + 0.587*132 + 0.114*132 = 39 + 77 + 15 Hogy valóban kerekíti e a JPEG algoritmus, erre nem találtunk választ, amennyiben igen, akkor az történik, hogy R= 129-132 pixelekre mind 39-et ad részeredménynek, vagyis 4 vörös tónus-luminanciát nem fog tudni megkülönböztetni a konverzió során. A zöldnél nincs kerekítési hiba, de a kék csatorna esetében 132-140 között mind 15-ös részeredmény fog születni, tehát 9 kék tónust fog egyetlen luminancia-számra leképezni. A visszaalakításnál gyakorlatilag a kék csatorna szenved(het)i el a legdurvább sávosodást, a zöld meg a legkevesebbet (a képletből ez értelemszerű). Konkrétan a fenti példa konvertálás után R131 G131 B131 lesz.
Ez azonban nincsen így. Ha igaz lenne, akkor egy R129 G132 B140 pixel JPEG-be mentése után visszanyitva R135 G134 B143 kellene legyen az eredmény. De nem az. Kipróbáltuk. Valószínűleg a számítások során végig lebegőpontosakat használ és akkor nincs szükség kerekítésre. Írtunk is a szerzőnek, egy hete nem válaszolt.
Konklúzió?
Ti mit gondoltok, illetve hogyan lehetne ezt kísérletileg megfogni? 

2017. okt. 5.

JPEG összefoglaló 6 - A generációs veszteség újramentések esetén

A JPEG-ről mindenki tudni véli a tuttit. Ugye kocsmában is feszt ez megy, vagy politika, vagy foci, de leginkább a JPEG. De vajon az előző posztok alapján mernénk e fogadni egy láda sörben, a következő állításokkal kapcsolatban? A kérdéseket kiemeltem, továbbolvasás előtt lehet tippelgetni. 


A JPEG mentés poszterizációt okoz. A jobboldali hisztogram egy durván veszteséges JPEGmentés eredménye.

1. A Nikon D5000 Fine JPEG (bármilyen gép, bármilyen minőségbeállítása) megfeleltethető e a Photoshop JPEG beállításaival? 
A kérdés  azért  jogos, mert létezik a mítosz, hogy ugyanazzal a kvantálási mátrixszal mentve, nem romlik a képminőség (lásd a 3. pontot is). Nem megfeleltethető. A PS mindig ugyanazokat a kvantálási mátrixokat használja, míg a fényképezőgépek minden képet elemeznek, és annak megfelelő táblákat hoznak létre (custom adaptive - nem jártunk utána, hogyan csinálja). Nem lehet sem a Nikon, sem a PS kvantálási tábláihoz hozzápiszkálni kívülről. Megnézni szerencsére lehet ( JPEGsnoop). Az értékei egymás mellé rendezve:


Jól látszik, hogy a PS12  alacsonyabb,
a PS11 viszont magasabb értékekkel operál, mint a D5000 FINE saját táblája
A fileméret szintén azt bizonyítja, hogy a Nikon Fine beállítása (ebben a konkrét esetben) valahol a PS 11-12 értékei között van félúton.

1.1. De legalább a Photoshop Save As... illetve Save for Web beállításai egymással megfeleltethetőek e? Nem. Az internet tele van megfeleltetési táblázatokkal, a kétfajta mentés között, ennek gyakorlati hasznát nem látjuk, mert az alkalmazott kvantálási táblázatok szerint, pontosan úgysem fedik egymást a beállítások. Viszont nem igaz az, amit valahol olvastunk, hogy pl. a Save for Web... 90-100% megegyezik a Save As... 12-es értékével és így tovább lefele. Még a 99% és a 100% is külön kvantálást használ (a 63 kvantálási tényezőből 3 eltér).

2. Ha nem változik a blokkméret (nem volt vágva a kép), és a blokk tartalma (semmilyen színbeavakozás nem történt), ugyanazzal a kvantálási táblázattal újra- meg újramentve, akkumulálódik e a generációs veszteség? A kérdés azért jogos, mert a kvantálás felel leginkább a veszteségért. Másrészt meg elvi, mert minek menteni egy képet, ha semmit csinálunk vele.
A válasz érdekes. A High beállításoknál minden mentéssel nő a veszteség. A Low beállítások felé haladva viszont egyre kevésbé romlik a kép az újramentések során (lásd alább). 
Az alábbi képen csak újramentés történt, semmilyen más beavatkozás nem volt. Az ábrákon a 00 generáció a legelső JPEG mentést jelenti, az original pedig a veszteségmentes eredetit.
PS 10 és 12 beállítás hatása 25 újramentésen keresztül
A 25 mentés során szinte nem volt látható veszteség a magasabb frekvenciás részeken, viszont az alacsony frekvenciás részek igencsak sávosodtak. Magyarul, a sziklát, ágakat szemmel láthatóan nem bántotta a huszonötszörös újratömörítés, az ég viszont szétesett már a 10. mentésnél. Ami ellentmond a kvantálásnál tanultakkal, hogy kifejezetten a nagyfrekvenciás részleteket tizedelik. Vagy nem mond ellent annak, hogy a látásunk megengedőbb a nagyfrekvenciás zónák veszteségével szemben, ezért csak az alacsony frekvenciás részeken észleljük a hibákat. Ezért most vizualizáljuk, pontosan miket érint a veszteség.
PS10 esetén a különbségek (veszteségek) a 0-12. illetve a 0-25. mentések között.
Jól látható, egy PS10-es beállítás mellett, hogy csakis korlátozott területeken megy végbe a rohamos romlás, míg más zónák (fekete részek) a 25. mentés után sem mutatnak eltérést a kiindulási képtől. 
Adja magát a kérdés, hogy mi történik alacsonyabb minőségbeállításnál. Hát ez:
Hát, szemre szinte nem lehet megállapítani a 25 generáció közötti különbséget. Az ég mindkettőn elég szederjes. Ami nem is meglepő, ha a különbségtérképet figyeljük:


Úgy tűnik, PS0 JPEG mentésnél nagyjából tökmindegy, hogy hányszor mentünk újra egy képet. A minőségromlás az első veszteséges mentéskor megtörténik (a 00 generációval), még van egy kis különbség a 0-1 generációk között, utána gyakorlatilag a kép változatlan marad, újramenthető kismilliószor, viszont ami kifejezetten érdekes, hogy a fileméret növekszik minden újramentéssel, mi azt gyanítjuk, a Huffman-kódolás miatt van ez.

Látható tehát, hogy Photoshopban a Maximumtól a Low irányában a sorozatos újramentések egyre kevésbé érintik a képminőséget. Viszont kritikus pont a legelső JPEG megszületése valamilyen veszteségmentes formából. Eddig az itt elveszített adatokat nem firtattuk. Most az eredetivel vetjük össze az első veszteséges mentést.
A fenti különbségtérkép jól mutatja, hogy PS0 beállításnál a legelső mentésnél jóval nagyobb a veszteség, mint PS12-nél.

Viszont az is világos, hogy a 0 beállítás egyetlen mentés alatt többet elveszít a képből, mint a 12-es beállításból 25 mentés. Plusz még az is kiderült, hogy a minőségibb beállítások (sorozatos újramentésnél) hajlamosabbak a homogén felületeket rombolni, míg az alacsony minőségű tömörítések inkább a részleteket rombolják,  a homogén felületeket kevésbé. Pl. 25 újramentés után a JPEG12 ege rosszabbul fog kinézni, mint a JPEG0 beállításé (akárhány mentés után, mivel ott az első pár mentés a releváns csak).

3. Érdemes e nagyobb minőségűre újramenteni egy JPEG-et a kevesebb veszteség érdekében, vagy inkább ugyanannál a beállításnál érdemesebb maradni? Úgy gondoljuk, hogy JPEG mentésnél minőségjavulás sohasem fordulhat elő újramentés során, ezért a minőségvesztés lecsökkentésére játszhatunk csupán. A kérdés szintén elméleti, ugyanis a valóságban ez leginkább úgy fordulhat elő, hogy a fényképezőgép készít egy nagyjából PS10-11-nek megfelelő tömörítést, ezt Photoshopban szerkesztés után meg PS12-nek mentjük el, remélve, hogy ezzel teszünk a legjobbat a képnek. Mint az első pontban kiderült nem merül fel, hogy pontosan ugyanolyat tudjunk menteni, mivel PSben nem enged személyreszabott kvantálási tényezőket. Amennyiben egy előzőleg is PS-ben mentett képpel van dolgunk, amit nem maximumon mentettek, akkor az alábbi a helyzet. 100%-ban nézzétek.
JPEG10-ből JPEG10
JPEG10-ből JPEG12
Az első különbségtérkép JPG10-ből JPG10-nek visszamentve, a második pedig JPG10-ből JPG12-nek mentve. Míg az első esetben inkább a homogén felületeken és izolált foltokban van elég durva veszteség, a felfele mentésnél szinte a teljes képre kiterjedő a rombolás apróbb, de szétszórtabb formában. Ebből sajnos nem tudjuk még kijelenteni, hogy melyik megoldás jobb vagy rosszabb, ugyanis a különbségtérkép csak azt árulja el, hol történt változás, de ennek szubjektív hatásáról semmit állít. A 2. pont tanulságai alapján viszont alacsonyabb minőségbeállításnál célszerűbb ugyanarra a beállításra visszamenteni, hiszen láttuk, hogy pár mentés után ott már nincs negatív hatása az újramentéseknek.

A fenti esetek, mint említettük, csupán elméleti jelentőségűek, a következő bejegyzésben azt is firtatjuk, mi van akkor, hogyha a mentések között olyan beavatkozások történnek, amelyek felvetik az újrablokkosítást, esetleg a tónusok változását (más DCT táblák keletkeznek).

2017. okt. 3.

JPEG alapok 5 - color subsampling

a 8x8-as tömbösödés mellett egy 16*16-os színtömbösödés is észrevehető helyenként. Ennek a 2:2 subsampling az oka.
Ez a lépés nem kötelezően fordul elő a JPEG kódolása során. Ezért, külön próbálunk kapcsolódni hozzá. Ha valaki tudja a magyar szakkifejezést, ne titkolja. Amúgy meg voltam győződve, hogy nem is nehéz téma, kicsi átlagolás ide-oda. De nem. A bejegyzés végére sem fogunk sokkal közelebb kerülni a megértéshez.

Az RGB - YCbCr átalakítás után következik, még a DCT előtti lépésben, így használható ki legjobban a fileméret csökkentő hatása. Definíció szerint a kroma subsampling alacsonyabb felbontású színcsatorna kódolást jelent (a luminancia csatorna kódolásához képest), egy chrominance pixel 2, 4, 8 szorosa a luminance pixelnek, kihasználja a szem gyengeségét a színek észlelésében. YCbCr színtérben gondolkodva, ez azt jelenti, hogy a luminancia csatorna érintetlen marad, a Cr és a Cb csatornákat pedig lehet rozsolni. Persze vannak olyan esetek, ahol a színinformáció is irtó fontos tud lenni, pl. orvosi, térinformatikai képalkotásban. De a facebookon aztán töknyolc. Mellesleg ott 2x2-es. Kipróbáltam.

RGB és Lab összehasonlítás 2x2-es color (a,b) subsampling
A Lab a,b csatornáin jól látszik, hogy 4 pixel ugyanazt a színt kódolja.



Ha az interneten keresgélni kezdenél ebben a témában, tuttifix, hogy a J:a:b  rendszer lesz amibe leginkább belebotlasz. Ideszúrom azért Douglas A. Kerr munkáját, amiben az elnevezések között vág rendet. Ennyire mélyen most nem megyünk bele, csupán pár szóban, a J a blokk (általában 4x2 pixel) száma vízszintesen , az a a felső vízszintes sorban, a b az alsó sorban található kroma-pixelek száma.  Ezt csak itt megmutatjuk, majd megyünk is tovább...
Forrás
...ugyanis nekünk a JPGsnoop, exiftool meg a társaik teljesen más elnevezést mutatnak, ezért ennek eredünk a nyomába.
A fenti ábra a Nikon D5000 Fine beállítás subsamplingjét mutatja.
Még egy indok, hogy RAW-ba dolgozzunk, a drága cucc simán kidobja az információ 33 százalékát.

Az 1x1 (4:4:4) gyakorlatilag nem is subsampling, minden pixel a maga jogán van elkódolva, ahogy kell.  A luminanciát nem is szokás subsamplingelni, mert minek.
Amennyiben minden csatorna 1x1 lenne, akkor valahogy így történne a kódolás:
YCbCr, YCbCr, YCbCr... stb., azaz pixelenként 3 byte. Így ment a PS 7-es minőségtől felfele.
A két kroma csatornának a fenti példában viszont 2x1-es subsamplingja van (4:2:2), ami azt jelenti, hogy két szomszédos kroma-pixel értéke kiátlagolódva egyetlen egyszer kerül elkódolásra. Így:
YYCbCr, YYCbCr, YYCbCr...  vagyis két pixelenként 4 byteon kódol 6 helyett. Így ment a Nikon D5000 Fine módban.
Van ennél is durvább tömörítése a színeknek, a 2x2 (4:2:0), ami értelemszerűen mindkét irányba két pixelt, vagyis négyet átlagol ki.
YYYYCbCr, YYYYCbCr...  négy pixelen 6 byte, 12 helyett. Ilyen az Assus Fine beállítása (!), a Photoshop JPEG mentése 6-os szint alatt, facebook stb.
Van még olyan is, hogy 4x4, de ezt pl. a PS nem alkalmazza, ilyenkor aztán 16 kroma pixel kerül kiátlagolásra, ami már azért a színlátásban bénácska látást sem tudja kicselezni.
YYYYYYYYYYYYYYYYCbCr - viszont csökkenti a fileméretet rendesen, 16 pixel csak 18 byte.


A fenti ábra jól mutatja mivel jár a color subsampling pixeles szinten. A PS 12-7-es JPEG minőségnél 1X1-es chroma subsamplinget használ. 6-0 között viszont 2x2-est.  Erről majd lesz szó. Persze egy 2x2-es beállítás nem fog jelentős colorshiftet eredményezni >4 pixeles színfoltok esetén, de viszont előfordulhatnak olyan helyzetek a képen, finom textúrák, pl. színes tarka ruhadarab, amin a csíkok nagyságrendje a subsampling zónába esik, és emiatt teljesen más színt fogunk kapni a JPEG kódolása után.
De azért nem egy rossz technika, mert bár teljesen más színek keletkeznek (jobb és baloldal)...

... viszont a mindennapi fotográfiában. 1:1 méretben, azért elég jól eltalálja a tónusokat:


Másik érdekesség a PS 00 értákre tömörített képen, hogy YCbCr módban ugyan látszik a két chroma csatornán a 2x2-es tömbösítés, de valamiféle turpisságot használ visszakonvertáláskor. Gyanítjuk, hogy valamilyen antialiase lehet. 

2017. szept. 29.

Valóban jobban látunk kontrasztot, mint színeket?

A cím meglehetősen pongyola (fényesség vs színesség a téma), de mindjárt kiderül miről van szó. Már egy jó csomószor meghivatkoztam, hogy az emberi látás, meg a luma, meg a chroma, de semmit se nem hiszünk el senkinek, ezért legyen itt egy félperces, elég butácska, de szerintem meglehetősen szemléletes példa. Persze a PS nem tud direkt módon YCbCr-be konvertálni, tehát trükközünk picit. Nem én találtam ki, a netről nyaltam nektek.
Originál
A kiindulási képből Desaturate paranccsal létrehozzuk a Luminancia réteget, majd a kiindulási képet 25%-ra csökkentjük (Best for reduction). majd 400%-ra növeljük kétféleképpen. Egyik a Smooth (jobboldali), másik a Hard (baloldali) interpoláció. Ezeket visszahelyezzük a deszaturált rétegre, Color Blending mode beállítással. 
 Az előbbi módszer fordítottját végezzük el, az alapréteg most a színes eredeti lesz, a deszaturált réteg kap most 2x2-es subsamplinget, majd visszahelyezve a színes rétegre, Luminosity blending módot állítunk.  
A képeket 100%-ban nézzétek, ofkorsz, a jobb sarokban egy 200% nagyítást is kaptok. Asszem magukért beszélnek. Innentől nem kérdés, hogy van létjogosultsága a color subsamplingnek. 

Találtam egy ilyet is valami powerpointban (sajni nem tudom belinkelni, keressétek meg, mert jó):

Azért is sznájpoltam ide, mert nemcsak a luma-chroma kérdést világítja meg, hanem visszacsatolhatunk a Diszkrét koszinusz transzformációhoz is. Jól megfigyelhető, miért állították azt, és a nyomukban én is szajkóztam, hogy a látás a nagyfrekvenciás jelekre kevésbé érzékeny, mint az alacsonyabbakra. Na ezér. 

2017. szept. 28.

JPEG alapok 4 - Futamidő- és Huffman-kódolás

Előzménye a DCT kvantálása. Na, ebben a részben történik meg a tömörítés, ami önmagában veszteségmentes folyamat (a veszteség már a kvantálás során keletkezett).


A kvantált DCT
5. A kvantálás utáni mátrixból egymás után rendezzük frekvencia szerint az AC értékeket, aminek hatására a DC után először az alacsony, majd a magas frekvenciák lesznek egymás után fűzve. Gyakorlatilag egy kétdimenziós táblából egydimenziósat csinálunk. Ennek az a célja, hogy többnyire hasonló elemek (főleg a zérósok) nagy számban rendeződjenek egymás mellé. Emlékszünk, ezért nyírtuk ki a nagyfrekvenciás jeleket a tömbünk jobb alsó régiójában, hogy ez megtörténjen. Első érték tehát a DC (0,0 pozíció), jelen esetben a -26, ami a teljes blokk átlaga is egyben, azután az alacsony frekvenciák felől haladunk a magas frekvenciák felé, vagyis a jobb alsó sarok irányába. Így:
-26 -3 0 -3 -3 -6 2 4 1 -4 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 
A DC értéket amúgy az előző blokkhoz viszonyítva bonyolultabbul menthetik, arra alapozva, hogy a szomszédos blokkok átlagai közel esnek egymáshoz, inkább a kis méreten kódolható eltérést kódolják, mint a nagydinamikájú adatot, ebbe most nem megyünk bele.

Na innen kezdve aztán elég sokféleképpen magyaráz az internet. A futamhossz-kódolást (run-lenght-encode) többnyire szöveggel és karaktereinek kódolásával mutatják be, de volt aki nem átallotta almákkal és banánokkal. Na midegy, mi képpel dolgozunk. Azt a módszert vesszük át, amit a leghitelesebbnek ítéltünk meg (8 perc környékén tér rá erre Amir úr).

A futáshossz-kódolás (RLE) lényege, hogy az egymást követő azonos értékeket pl. zérósok (más weboldalakon, videókban minden ismétlődő érték), ne fogyasszanak sok tárhelyet. Csökkentjük a redundanciát, de mi most csak a nullásokkal (azér' kvantáltunk, hogy jó sok legyen), olyan formában, hogy megadjuk a zérósok számát (r), majd az azokat követő AC érték tárolására szükséges bitek számát (s) - innen fogja tudni a kiolvasó program, hogy pontosan mit kell kiolvasni, mint AC adatot, majd magát a zérósokat követő AC értéket magát (c).

 [(r,s),c]
Tehát a sorunk elemein végighaladva:
-26 -3-3 -3 -6 2 4 1 -4 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,5),-26] - mivel a DC az első elem, ezért itt az r=0, és máris belefutottunk Amir Nagah videójában egy érdekességre. Ő azt állítja, hogy -26 elkódolható s=5 biten. Felmerült bennem, hogy a negatív előjellel meg mi van? Írtam is neki kérdés-kommentet, lám mit válaszol.
[(0,2),-3] - a második érték előtt sincs zérós, -3 meg Amir szerint 2 biten tárolható. Egyelőre ezzel tárhelyet pazarlunk, de nézzük a zöld zónát:
[(5,1),-1] - 5 zérós előzi meg a -1-et. Itt már 3 számmal írtunk le ötöt, de az igazán érdekes az a feketével kiemelt sor:
[(0,0)] -  ez az EOB jel, ha az r és az s is nullás, akkor innentől a blokk végéig mind zérós jön. Na itt történik a nagy redundanciacsökkentés és tömörítés. 

Amir a videójában azt állítja, hogy a JPEG-ben minden (r,s) párost egyetlen byte ír le, amiből a felső négy bit az r, az alsó négy bit az s. Amennyiben az r nem elég (a zérósok száma >15), több rövidebb futamhossz-kódolásból oldják meg. Az s értékére max. 11-et ír (15 helyett), ennek köze lehet a fent említett előjel-problémának a megoldásához (lássuk mit válaszol). 11 biten mellesleg 2047-ig kódolhatunk. Gyakorlatilag tehát az történik, hogy 15 nullást egyetlen byte kódolhat el. Az EOB byte meg bármennyi nullást.

Egy valós képen, ahol a 8*8-as blokkok homogének és nagyobb felületeken sem nagyon ütnek el egymástól (pl. a fél képen kék ég húzódik), egyes (r,s) párosok sokkal gyakrabban fognak előfordulni, mint mások. Tehát ha a  [(r,s),c] sorozatokat egymás után fűzzük (binárisan persze), akkor lesznek benne patternek, amelyek gyakran fordulnak elő, mások kevésbé. Ezeket érdemes helyettesíteni, a gyakoriakat rövidebb szimbólummal, a ritkábbakat hosszabbal, így további tárhely spórolható meg. 

Ezt csinálja a Huffman kódolás (ebből is többféle van), bár létezik JPEG-ben aritmetikai kódolás is, ami még nagyobb tömörítést eredményez, viszont macerásabb (talán a JP2000, de arra a körhintára nem kívánunk felülni). Lényege az, hogy az elkódolni kívánt elemeket statisztikai gyakoriságuk szerint rendezi, a kevésbé gyakori elemekhez rendel nagyobb címet, a gyakoriakat pedig kevés biten kódolja. A youtube tele van magyarázatokkal, ne spóroljátok meg. Én sem írnám le jobban. Ezt a tömörítést az interneten általában szövegkódolással illusztrálják, tegyünk így mi is, egy Eminem nótában pl. a fuck szó lenne a legrövidebben megcímezve, a hegeli dialektika pedig a leghosszabban (de lehet, hogy tévedek és ilyet egyszer se mondott ki). Tipikus programozói feladat. Azért egy képernyőképet ideszúrok magamnak emlékeztetőnek. Az a1, a2 stb. a kódolni kívánt elemek, pirossal az előfordulásuk gyakorisága jelenik meg. Sárga mezőben pedig az elkódolásukhoz szükséges bináris cím.
Az így keletkezett címeket egymás után írjuk. A legszebb ebben a trükkben az, hogy míg a szavakat szóközök jelzik, a morzéban meg pl. szünet vezeti be a következő jelet, itt a teljes hosszú bit-kolbászban nincs szükség elválasztó szimbólumokra az egyes jelek között, maga a kiolvasási rendszer garantálja a helyes visszakódolást:
például legyen ez a Huffman-kódolt bitstream: 010110101010011101001011101010110010101010
A fenti bináris fa segítségével sorban kiolvassuk. A színek jelzik, melyik szimbólumot melyik szakaszból vesszük: a1, a2, a3a2, a2, a2, a1, a4, a1, a2, a1, és így tovább, egyszerűen nem lehet másképp kiolvasni.

Minden képnek saját bináris fája van, természetesen a visszafejtéshez a JPEG filenak tartalmaznia kell az adott adathalmaz visszafejtéséhez szükséges információkat. A Huffman-kódot is lehet tweakelni a haladóbbaknak, a jobb eredmény érdekében. Mi azonban csak tátjuk a szánkat, a JPEGsnoppal ilyesmiket találtunk Huffman kulcsszóra a tesztekhez használt képünkben:
Egy random JPEG Huffman eloszlása. A DC tábla nyilván jóval kevesebb információt (12) kódol, az AC meg 256-ot.

A táblázatok statisztikai eloszlásából jól látszik, hogy bár eredetileg minden egyes értékre 8 bit kellene, közel felüket 2 bitből meg lehet címezni. Bár van olyan ritkán előforduló adat, ami akár 16 bitet használ el, azért a nyereség elég látványos. A 0% értékek becsapósak, valamiért a JPEGsnoop nem tud egynél kisebb értékeket itt megjeleníteni. 










Mivel a százalék értékek nem pontosak, csak a nagyságrend számolható ki, a négy tábla összes adata megegyezik a 12 megapixeles kép összes pixeleinek a számával. Eben az esetben a DC táblázatban az látszik, hogy a leggyakoribb adatokat 3 biten kódolja, de találtunk olyan képet is, amiben már 1 biten. Gondolom ez azon múlik, milyen bináris fát sikerül létrehozni (levél-ág, vagy ág-ág szerkezet van a gyökér után).

A tömörítésben még van egy fontos tényező, a subsampling, de mivel azt nem mindig alkalmazzák, külön tárgyaljuk a következő részben. Nagyjából ennyi volt a JPEG elkódolása, megnyitáskor pedig ugyanezek a folyamatok fordítva játszódnak le. Ennyike.