Hur JPEG-formatet fungerar

JPEG-bilder är allestädes närvarande i våra digitala liv, men bakom denna faner av medvetenhet finns algoritmer som tar bort detaljer som inte är märkbara för det mänskliga ögat. Resultatet är den högsta visuella kvaliteten i den minsta filstorleken - men exakt hur fungerar det hela? Låt oss se vad exakt våra ögon inte ser!

Hur JPEG-formatet fungerar

Det är lätt att ta för givet möjligheten att skicka ett foto till en vän och inte oroa sig för vilken enhet, webbläsare eller operativsystem de använder – men det var inte alltid fallet. I början av 1980-talet kunde datorer lagra och visa digitala bilder, men det fanns många konkurrerande idéer om det bästa sättet att göra detta. Du kunde inte bara skicka en bild från en dator till en annan och hoppas att det skulle fungera.

För att lösa detta problem sammansattes en kommitté av experter från hela världen 1986 kallad "Gemensam grupp av fotoexperter» (Joint Photographic Experts Group, JPEG), grundad som en gemensam ansträngning mellan International Organization for Standardization (ISO) och International Electrotechnical Commission (IEC), två internationella standardiseringsorganisationer med huvudkontor i Genève, Schweiz.

En grupp människor som heter JPEG skapade JPEG-standarden för digital bildkomprimering 1992. Alla som har använt internet har förmodligen stött på JPEG-kodade bilder. Detta är det vanligaste sättet att koda, skicka och lagra bilder. Från webbsidor till e-post till sociala medier, JPEG används miljarder gånger om dagen – praktiskt taget varje gång vi tittar på en bild online eller skickar den. Utan JPEG skulle webben vara mindre färgstark, långsammare och förmodligen ha färre kattbilder!

Den här artikeln handlar om hur man avkodar en JPEG-bild. Med andra ord, vad som krävs för att konvertera komprimerad data lagrad på en dator till en bild som dyker upp på skärmen. Detta är värt att veta, inte bara för att det är viktigt att förstå tekniken vi använder varje dag, utan också för att vi genom att låsa upp kompressionsnivåer lär oss mer om perception och syn, och vilka detaljer våra ögon är mest känsliga för.

Dessutom är det väldigt intressant att leka med bilder på det här sättet.

Hur JPEG-formatet fungerar

Tittar inuti JPEG

På en dator lagras allt som en sekvens av binära tal. Vanligtvis är dessa bitar, nollor och ettor, grupperade i grupper om åtta för att utgöra byte. När du öppnar en JPEG-bild på en dator måste något (en webbläsare, ett operativsystem, något annat) avkoda byten, vilket återställer den ursprungliga bilden som en lista över färger som kan visas.

Om du laddar ner denna söta foto av en katt och öppna den i en textredigerare, kommer du att se ett gäng osammanhängande tecken.

Hur JPEG-formatet fungerar
Här använder jag Notepad++ för att undersöka innehållet i filen, eftersom vanliga textredigerare som Notepad på Windows kommer att förstöra den binära filen efter att ha sparats och den inte längre uppfyller JPEG-formatet.

Att öppna en bild i en ordbehandlare förvirrar datorn, precis som du förvirrar din hjärna när du gnuggar dina ögon och börjar se färgfläckar!

Dessa fläckar du ser är kända som fosfener, och är inte resultatet av en lätt stimulans eller en hallucination som genereras av sinnet. De uppstår för att din hjärna tror att alla elektriska signaler i synnerverna förmedlar information om ljus. Hjärnan behöver göra dessa antaganden eftersom det inte finns något sätt att veta om en signal är ett ljud, en syn eller något annat. Alla nerver i kroppen överför exakt samma elektriska impulser. Genom att trycka på dina ögon skickar du signaler som inte är visuella, utan aktiverar ögats receptorer, vilket din hjärna tolkar – i det här fallet felaktigt – som något visuellt. Du kan bokstavligen se trycket!

Det är roligt att tänka på hur lika datorer är hjärnan, men det är också en användbar analogi för att illustrera hur mycket betydelsen av data – oavsett om den bärs genom kroppen av nerver eller lagras på en dator – beror på dess tolkning. All binär data består av XNUMX:or och XNUMX:or, de grundläggande komponenterna som kan förmedla information av alla slag. Din dator kommer ofta på hur man tolkar dem genom att använda ledtrådar som filtillägg. Nu tvingar vi den att tolka dem som text, för det är vad textredigeraren förväntar sig.

För att förstå hur man avkodar JPEG måste vi se själva originalsignalerna - de binära data. Detta kan göras med hjälp av en hexadecimal editor, eller direkt på webbsida för originalartikel! Det finns en bild, bredvid vilken i textfältet finns alla dess byte (förutom rubriken), presenterad i decimalform. Du kan ändra dem, och skriptet kodar om och producerar en ny bild i farten.

Hur JPEG-formatet fungerar

Du kan lära dig mycket bara genom att spela med denna editor. Kan du till exempel berätta i vilken ordning pixlarna är lagrade?

Det märkliga med det här exemplet är att att ändra vissa siffror inte påverkar bilden alls, men om du till exempel byter ut siffran 17 mot 0 på första raden så blir bilden helt förstörd!

Hur JPEG-formatet fungerar

Andra ändringar, som att ersätta 7:an på linje 1988 med siffran 254, ändrar färgen, men bara på efterföljande pixlar.

Hur JPEG-formatet fungerar

Det kanske konstigaste är att vissa siffror ändrar inte bara färgen, utan även bildens form. Ändra 70 på rad 12 till 2 och titta på den översta raden i bilden för att se vad jag menar.

Hur JPEG-formatet fungerar

Och oavsett vilken JPEG-bild du använder, kommer du alltid att hitta dessa mystiska schackmönster när du redigerar byten.

När man spelar med redigeraren är det svårt att förstå hur ett foto återskapas från dessa bytes, eftersom JPEG-komprimering består av tre olika teknologier, applicerade sekventiellt i nivåer. Vi kommer att studera var och en separat för att avslöja det mystiska beteendet vi ser.

Tre nivåer av JPEG-komprimering:

  1. Färg delsampling.
  2. Diskret cosinustransformation och sampling.
  3. Körlängdskodning, delta и Huffman

För att ge dig en uppfattning om storleken på komprimeringen, notera att bilden ovan representerar 79 819 nummer, eller cirka 79 KB. Om vi ​​lagrade den utan komprimering skulle varje pixel kräva tre nummer – för de röda, gröna och blå komponenterna. Detta skulle uppgå till 917 700 nummer, eller ca. 917 KB. Som ett resultat av JPEG-komprimering reducerades den slutliga filen med mer än 10 gånger!

Faktum är att den här bilden kan komprimeras mycket mer. Nedan finns två bilder sida vid sida - bilden till höger har komprimerats till 16 KB, det vill säga 57 gånger mindre än den okomprimerade versionen!

Hur JPEG-formatet fungerar

Om du tittar noga kommer du att se att dessa bilder inte är identiska. Båda är bilder med JPEG-komprimering, men den högra är mycket mindre i volym. Det ser också lite sämre ut (titta på bakgrundsfärgsrutorna). Det är därför JPEG också kallas förlustkomprimering; Under komprimeringsprocessen ändras bilden och vissa detaljer förloras.

1. Färg delsampling

Här är en bild med endast den första nivån av komprimering tillämpad.

Hur JPEG-formatet fungerar
(Interaktiv version - in original artiklar). Att ta bort ett nummer förstör alla färger. Men om exakt sex siffror tas bort har det praktiskt taget ingen effekt på bilden.

Nu är siffrorna lite lättare att tyda. Detta är nästan en enkel lista med färger, där varje byte ändrar exakt en pixel, men samtidigt är den redan hälften så stor som den okomprimerade bilden (vilket skulle ta upp cirka 300 KB i en sådan reducerad storlek). Kan du gissa varför?

Du kan se att dessa siffror inte representerar de vanliga röda, gröna och blå komponenterna, eftersom om vi ersätter alla siffror med nollor får vi en grön bild (snarare än vit).

Hur JPEG-formatet fungerar

Detta beror på att dessa byte står för Y (ljusstyrka),

Hur JPEG-formatet fungerar

Cb (relativ blåhet),

Hur JPEG-formatet fungerar

och Cr (relativ rodnad) bilder.

Hur JPEG-formatet fungerar

Varför inte använda RGB? Det är trots allt så de flesta moderna skärmar fungerar. Din bildskärm kan visa vilken färg som helst, inklusive röd, grön och blå, med olika intensiteter för varje pixel. Vitt fås genom att slå på alla tre med full ljusstyrka och svart genom att stänga av dem.

Hur JPEG-formatet fungerar

Detta är också väldigt likt hur det mänskliga ögat fungerar. Färgreceptorerna i våra ögon kallas "kottar“, och är indelade i tre typer, som var och en är mer känslig för antingen röda, gröna eller blå färger [S-typ kottar är känsliga i det violett-blå (S från engelska Short - short-wave spectrum), M -typ - i de gröngula (M från engelska Medium - medium-wave), och L-typ - i de gulröda (L från engelska Long - long-wave) delarna av spektrumet. Närvaron av dessa tre typer av kottar (och stavar, som är känsliga i den smaragdgröna delen av spektrumet) ger en person färgseende. / cirka. översätt]. pinnar, en annan typ av fotoreceptor i våra ögon, kan upptäcka förändringar i ljusstyrka, men är mycket känsligare för färg. Våra ögon har cirka 120 miljoner stavar och bara 6 miljoner kottar.

Det är därför våra ögon är mycket bättre på att upptäcka förändringar i ljusstyrka än förändringar i färg. Om du skiljer färg från ljusstyrka kan du ta bort lite färg och ingen kommer att märka något. Chroma subsampling är processen att representera färgkomponenterna i en bild med en lägre upplösning än luminanskomponenterna. I exemplet ovan har varje pixel exakt en Y-komponent, och varje enskild grupp om fyra pixlar har exakt en Cb- och en Cr-komponent. Därför innehåller bilden fyra gånger mindre färginformation än originalet.

YCbCr-färgrymden används inte bara i JPEG. Den uppfanns ursprungligen 1938 för tv-program. Alla har inte en färg-TV, så att separera färg och ljusstyrka gjorde att alla kunde få samma signal, och TV-apparater utan färg använde helt enkelt bara ljusstyrkans komponent.

Så att ta bort ett nummer från editorn förstör helt alla färger. Komponenterna lagras i formen YYYY Cb Cr (i själva verket inte nödvändigtvis i den ordningen - lagringsordningen anges i filhuvudet). Om du tar bort den första siffran kommer det första värdet på Cb att uppfattas som Y, Cr som Cb, och i allmänhet kommer du att ha en dominoeffekt som växlar alla färger i bilden.

JPEG-specifikationen tvingar dig inte att använda YCbCr. Men de flesta filer använder det eftersom det ger bättre nedsamplade bilder än RGB. Men du behöver inte ta mitt ord för det. Se själv i tabellen nedan hur delsampling av varje enskild komponent kommer att se ut i både RGB och YCbCr.

Hur JPEG-formatet fungerar
(Interaktiv version - in original artiklar).

Avlägsnandet av blått är inte lika märkbart som rött eller grönt. Det beror på de sex miljoner kottarna i dina ögon, cirka 64% är känsliga för rött, 32% för grönt och 2% för blått.

Nedsamplingen av Y-komponenten (nedre till vänster) syns bäst. Även en liten förändring märks.

Att konvertera en bild från RGB till YCbCr minskar inte filstorleken, men det gör det lättare att hitta mindre synliga detaljer som kan tas bort. Förlustkompression inträffar i det andra steget. Det bygger på idén att presentera data i en mer komprimerbar form.

2. Diskret cosinustransformation och sampling

Denna nivå av komprimering är för det mesta vad JPEG handlar om. Efter att ha konverterat färgerna till YCbCr komprimeras komponenterna individuellt, så att vi kan koncentrera oss på bara Y-komponenten. Och så här ser Y-komponentbyten ut efter att ha applicerat detta lager.

Hur JPEG-formatet fungerar
(Interaktiv version - in original artiklar). I den interaktiva versionen rullar redigeraren till raden som representerar den genom att klicka på en pixel. Försök att ta bort siffror från slutet eller lägga till några nollor till ett visst tal.

Vid första anblicken ser det ut som väldigt dålig kompression. Det finns 100 000 pixlar i en bild, och det krävs 102 400 siffror för att representera deras ljusstyrka (Y-komponenter) - det är värre än att komprimera ingenting alls!

Observera dock att de flesta av dessa siffror är noll. Dessutom kan alla dessa nollor i slutet av rader tas bort utan att bilden ändras. Det finns cirka 26 000 nummer kvar, och detta är nästan 4 gånger färre!

Denna nivå innehåller schackmönsters hemlighet. Till skillnad från andra effekter vi har sett, är utseendet på dessa mönster inte ett fel. De är byggstenarna i hela bilden. Varje rad i editorn innehåller exakt 64 siffror, diskreta cosinustransformering (DCT) koefficienter som motsvarar intensiteten av 64 unika mönster.

Dessa mönster bildas baserat på cosinusdiagrammet. Så här ser några av dem ut:

Hur JPEG-formatet fungerar
8 av 64 odds

Nedan är en bild som visar alla 64 mönstren.

Hur JPEG-formatet fungerar
(Interaktiv version - in original artiklar).

Dessa mönster är särskilt viktiga eftersom de utgör grunden för 8x8-bilderna. Om du inte är bekant med linjär algebra betyder det att vilken 8x8-bild som helst kan göras från dessa 64 mönster. DCT är processen att dela upp bilder i 8x8 block och omvandla varje block till en kombination av dessa 64 koefficienter.

Det verkar som magi att vilken bild som helst kan vara sammansatt av 64 specifika mönster. Detta är dock samma sak som att säga att vilken plats som helst på jorden kan beskrivas med två siffror - latitud och longitud [indikerar halvklot / ca. översätt]. Vi tänker ofta på jordens yta som tvådimensionell, så vi behöver bara två tal. En 8x8-bild har 64 dimensioner, så vi behöver 64 siffror.

Det är ännu inte klart hur detta hjälper oss när det gäller komprimering. Om vi ​​behöver 64 siffror för att representera en 8x8-bild, varför skulle detta vara bättre än att bara lagra 64 ljusstyrkakomponenter? Vi gör detta av samma anledning som vi förvandlade tre RGB-nummer till tre YCbCr-nummer: det låter oss ta bort subtila detaljer.

Det är svårt att se exakt vilken detalj som tas bort i detta skede eftersom JPEG tillämpar DCT på 8x8 block. Men ingen förbjuder oss att tillämpa det på hela bilden. Så här ser DCT ut för Y-komponenten som tillämpas på hela bilden:

Hur JPEG-formatet fungerar

Mer än 60 000 nummer kan tas bort från slutet med praktiskt taget inga märkbara förändringar på fotot.

Hur JPEG-formatet fungerar

Observera dock att om vi nollställer de första fem siffrorna kommer skillnaden att vara uppenbar.

Hur JPEG-formatet fungerar

Siffrorna i början representerar lågfrekventa förändringar i bilden, som våra ögon uppfattar bäst. Siffror mot slutet indikerar förändringar i de höga frekvenserna som är svårare att märka. För att "se vad ögat inte kan se" kan vi isolera dessa högfrekventa detaljer genom att nollställa de första 5000 siffrorna.

Hur JPEG-formatet fungerar

Vi ser alla de områden i bilden där den största förändringen sker från pixel till pixel. Kattens ögon, hans morrhår, frottéfilten och skuggorna i det nedre vänstra hörnet sticker ut. Du kan gå längre genom att nollställa de första 10 000 siffrorna:

Hur JPEG-formatet fungerar

20 000 XNUMX:

Hur JPEG-formatet fungerar

40 000 XNUMX:

Hur JPEG-formatet fungerar

60 000 XNUMX:

Hur JPEG-formatet fungerar

Dessa högfrekventa detaljer tas bort av JPEG under komprimeringsstadiet. Det finns ingen förlust i att konvertera färger till DCT-koefficienter. Förlust uppstår vid provtagningssteget, där högfrekventa eller nära nollvärden tas bort. När du sänker JPEG-lagringskvaliteten ökar programmet tröskeln för antalet värden som tas bort, vilket minskar filstorleken, men gör bilden mer pixlad. Det var därför bilden i det första avsnittet, som var 57 gånger mindre, såg ut så här. Varje 8x8-block representerades av mycket färre DCT-koefficienter jämfört med versionen med högre kvalitet.

Du kan skapa en så cool effekt som gradvis streaming av bilder. Du kan visa en suddig bild som blir mer och mer detaljerad när fler och fler koefficienter laddas ner.

Här, bara för skojs skull, är vad du får med bara 24 000 nummer:

Hur JPEG-formatet fungerar

Eller bara 5000:

Hur JPEG-formatet fungerar

Väldigt suddigt, men på något sätt igenkännbart!

3. Körlängdskodning, delta och Huffman

Hittills har alla kompressionsstadier varit förlustiga. Det sista steget, tvärtom, fortsätter utan förluster. Det tar inte bort information, men det minskar filstorleken avsevärt.

Hur kan man komprimera något utan att slänga information? Föreställ dig hur vi skulle beskriva en enkel svart rektangel 700 x 437.

JPEG använder 5000 nummer för detta, men mycket bättre resultat kan uppnås. Kan du föreställa dig ett kodningsschema som skulle beskriva en sådan bild i så få byte som möjligt?

Det minimala schemat jag kunde komma på använder fyra: tre för att representera en färg och en fjärde för att indikera hur många pixlar den färgen har. Idén med att representera upprepade värden på detta förtätade sätt kallas run-length-kodning. Det är förlustfritt eftersom vi kan återställa den kodade datan till dess ursprungliga form.

En JPEG-fil med en svart rektangel är mycket större än 4 byte - kom ihåg att på DCT-nivån tillämpas komprimering på 8x8 pixelblock. Därför behöver vi åtminstone en DCT-koefficient för varje 64 pixel. Vi behöver en eftersom istället för att lagra en DCT-koefficient följt av 63 nollor, tillåter körlängdskodning oss att lagra ett nummer och indikera att "alla andra är nollor."

Deltakodning är en teknik där varje byte innehåller en skillnad från något värde snarare än ett absolut värde. Därför ändrar redigering av vissa byte färgen på alla andra pixlar. Till exempel istället för att lagra

12 13 14 14 14 13 13 14

Vi kan börja med 12 och sedan helt enkelt ange hur mycket vi behöver lägga till eller subtrahera för att få nästa tal. Och denna sekvens i deltakodning tar formen:

12 1 1 0 0 -1 0 1

Den konverterade datan är inte mindre än den ursprungliga, men det är lättare att komprimera den. Att tillämpa deltakodning före körlängdskodning kan hjälpa mycket samtidigt som det fortfarande är förlustfri komprimering.

Deltakodning är en av få tekniker som används utanför 8x8 block. Av de 64 DCT-koefficienterna är en helt enkelt en konstant vågfunktion (helfärgad). Den representerar den genomsnittliga ljusstyrkan för varje block för luma-komponenterna, eller den genomsnittliga blåheten för Cb-komponenterna, och så vidare. Det första värdet för varje DCT-block kallas DC-värdet, och varje DC-värde deltakodas med avseende på de föregående. Därför kommer att ändra ljusstyrkan för det första blocket att påverka alla block.

Det sista mysteriet kvarstår: hur förstör det hela bilden om man ändrar singularis? Hittills har kompressionsnivåer inte haft sådana egenskaper. Svaret finns i JPEG-huvudet. De första 500 byten innehåller metadata om bilden – bredd, höjd osv, och vi har inte jobbat med dem ännu.

Utan en header är det nästan omöjligt (eller mycket svårt) att avkoda JPEG. Det kommer att se ut som om jag försöker beskriva bilden för dig, och jag börjar hitta på ord för att förmedla mitt intryck. Beskrivningen kommer förmodligen att vara ganska förtätad, eftersom jag kan hitta på ord med precis den betydelse jag vill förmedla, men för alla andra kommer de inte att vara vettiga.

Det låter dumt, men det är precis vad som händer. Varje JPEG-bild komprimeras med koder som är specifika för den. Kodordlistan lagras i rubriken. Denna teknik kallas Huffman-kod och vokabulären kallas Huffman-tabell. I rubriken är tabellen markerad med två byte - 255 och sedan 196. Varje färgkomponent kan ha sin egen tabell.

Ändringar av tabeller kommer att radikalt påverka alla bilder. Ett bra exempel är att ändra den 15:e raden till 1.

Hur JPEG-formatet fungerar

Detta händer eftersom tabellerna anger hur enskilda bitar ska läsas. Hittills har vi bara arbetat med binära tal i decimalform. Men detta döljer för oss det faktum att om du vill lagra siffran 1 i en byte kommer det att se ut som 00000001, eftersom varje byte måste ha exakt åtta bitar, även om bara en av dem behövs.

Detta är potentiellt ett stort slöseri med utrymme om du har många små nummer. Huffman-kod är en teknik som gör att vi kan lätta på kravet att varje nummer måste uppta åtta bitar. Detta betyder att om du ser två byte:

234 115

Sedan, beroende på Huffman-tabellen, kan dessa vara tre siffror. För att extrahera dem måste du först dela upp dem i enskilda bitar:

11101010 01110011

Sedan tittar vi på tabellen för att ta reda på hur vi grupperar dem. Detta kan till exempel vara de första sex bitarna, (111010), eller 58 i decimal, följt av fem bitar (10011), eller 19, och slutligen de fyra sista bitarna (0011), eller 3.

Därför är det mycket svårt att förstå byte i detta skede av komprimering. Bytes representerar inte vad de verkar. Jag kommer inte att gå in på detaljer om att arbeta med tabellen i den här artikeln, men material om denna fråga online tillräckligt.

Ett intressant knep du kan göra med denna kunskap är att separera rubriken från JPEG och lagra den separat. Det visar sig faktiskt att bara du kan läsa filen. Facebook gör detta för att göra filer ännu mindre.

Vad mer som kan göras är att ändra Huffman-bordet en hel del. För andra kommer det att se ut som en trasig bild. Och bara du kommer att veta det magiska sättet att fixa det.

Låt oss sammanfatta: så vad behövs för att avkoda JPEG? Nödvändig:

  1. Extrahera Huffman-tabellen/tabellerna från rubriken och avkoda bitarna.
  2. Extrahera de diskreta cosinustransformationskoefficienterna för varje färg- och luminanskomponent för varje 8x8-block, och utför transformeringar av omvänd körlängd och deltakodning.
  3. Kombinera cosinus baserat på koefficienter för att få pixelvärden för varje 8x8 block.
  4. Skala färgkomponenter om delsampling utfördes (denna information finns i rubriken).
  5. Konvertera de resulterande YCbCr-värdena för varje pixel till RGB.
  6. Visa bilden på skärmen!

Seriöst jobb för att bara titta på ett foto med en katt! Men det jag gillar med den är att den visar hur människocentrerad JPEG-teknik är. Det är baserat på särdragen i vår uppfattning, vilket gör att vi kan uppnå mycket bättre komprimering än konventionella tekniker. Och nu när vi förstår hur JPEG fungerar kan vi föreställa oss hur dessa teknologier kan överföras till andra områden. Till exempel kan deltakodning i video ge en betydande minskning av filstorleken, eftersom det ofta finns hela områden som inte ändras från bildruta till bildruta (till exempel bakgrunden).

Koden som används i artikeln, är öppen och innehåller instruktioner om hur du byter ut bilderna mot dina egna.

Källa: will.com

Lägg en kommentar