NBK schreef op maandag 30 mei 2005 @ 18:31:
Tis niet zo moeilijk hoor. Even beetje simpel uitgelegd, klopt niet helemaal...
JPEG maakt gebruik van het feit dat de kleur van veel pixels die naast elkaar liggen vaak minder van elkaar afwijking dan de waarde van de kleur tenopzichte van het nulpunt. Als je 3 pixel heb met kleurwaarde 253, 250 en 254 kun je dat in 3 keer een 8 bit waarde opslaan maar ook als een 7 bit waarde die dan 250 voorstelt en de 2 bits grootte waardes 3, 0 en 4. Doe dat in blokjes van 8x8 pixels en je bespaard een hoop bits.
Van PC's zijn we gewend dat ze met RGB werken maar er zijn meer kleurstandaarden in de wereld. Een daarvan is YUV. Je kunt een RGB kleur gewoon omrekenen naar de bijbehorende YUV waardes (
maar ik weet de formule even niet uit me hoofd). Y is de helderheid van een pixel. U en V zijn 2 waardes waarmee de kleur wordt bepaald. Je oog gevoeliger voor verschil in helderheid dan in kleur dus slaan ze per 4 Y pixels maar 1 U en 1 V pixel op. Alleen dat laatste truucje leverd al 50% data reductie op.
Ik was al bang dat mijn post een beetje te was. Maar goed, zo ben ik :-) Zoals het door NBK wordt uitgelegd is wel heel simpel gesteld. Jpeg (standaard, het kan ook anders) werkt als volgt:
- De RGB waardes worden omgerekend naar de YUV kleurruimte. Dit omdat ons oog veel gevoeliger is voor helderheid dan voor kleurverschillen. In YUV kleurruimte staat Y voor de helderheid in de U en de V staan voor de kleur.
- De U en V kanalen worden 2 bij 2 keer zo klein gemaakt. Dit dus vanwege die ongevoeligheid voor kleur. Een 640x480 plaatje bevat dus een 640x480 kanaal voor de helderheid en twee 320x240 kanalen voor de kleurinformatie.
- De informatie wordt opgedeeld in blokjes van 8 bij 8 pixels. Er worden dan steeds 4 blokken in het Y kanaal en 1 in elk van de U en V kanalen opgeslagen.
- Op elk blokje wordt een Discrete Cosine Transform (dct) toegepast. Het resultaat is nog steeds 64 waardes, maar deze waardes geven de grootte per frequentie aan i.p.v. van de directe waardes van de pixels. Dit omdat plaatjes relatief weinig informatie in de hogere frequentiebanden bevat. De eerste waarde van de 64 is eigenlijk gewoon het gemiddelde van de 64 pixels in het blokje van 8 bij 8. Dit wordt ook wel de dc-waarde genoemd.
- De 64 waardes worden gedeeld door de waardes in de quantization matrix. Dit is de stap waarin (de meeste) informatie wordt weggegooid. Meestal is het zo dat de waardes horend bij een hogere frequentie door een hoger getal worden gedeeld.
- De dc-waarde wordt relatief ten opzichte van de vorige dc waarde opgeslagen. In het Y kanaal bijvoorbeeld. Als de gemiddelde helderheid van het vorige blokje 210 is en die van het huidige blokje 195 dan wordt -15 opgeslagen.
- Daarna wordt er op de dc-waardes huffman compressie toegepast. Op de overige waardes wordt een combinatie van run length encoding en huffman compressie toegepast.
Maar goed, dit doet er niet echt toe. Het punt was eigenlijk dat als ik die plaatjes zo zie ik inschat dat er per plaatje maar 3 tot 5 bytes beschadigd zijn per stuk. Als je jpg-compressie kent zie je meteen de effecten die zo'n beschadiging heeft.