Si të konfiguroni telefonat inteligjentë dhe PC. Portali informativ
  • në shtëpi
  • Gabimet
  • Çfarë metode kompresimi përdor algoritmi jpeg. JPEG kompresohet më mirë se GIF

Çfarë metode kompresimi përdor algoritmi jpeg. JPEG kompresohet më mirë se GIF

Është e lehtë të llogaritet se një imazh i pakompresuar me ngjyra të plota prej 2000*1000 pikselësh do të jetë rreth 6 megabajt në madhësi. Nëse flasim për imazhe të marra nga kamerat profesionale ose skanerët me rezolucion të lartë, atëherë madhësia e tyre mund të jetë edhe më e madhe. Megjithë rritjen e shpejtë të kapacitetit të pajisjeve të ruajtjes, algoritme të ndryshme të kompresimit të imazhit janë ende shumë të rëndësishme.
Të gjithë algoritmet ekzistuese mund të ndahen në dy klasa të mëdha:

  • Algoritmet e kompresimit pa humbje;
  • Algoritmet e kompresimit me humbje.
Kur flasim për kompresim pa humbje, nënkuptojmë se ekziston një algoritëm i kundërt me algoritmin e kompresimit që ju lejon të rivendosni me saktësi imazhin origjinal. Për algoritmet e kompresimit me humbje algoritmi i anasjelltë nuk ekziston. Ekziston një algoritëm që rikthen një imazh që nuk përputhet domosdoshmërisht saktësisht me origjinalin. Algoritmet e kompresimit dhe rikuperimit zgjidhen për të arritur një shkallë të lartë kompresimi duke ruajtur cilësinë vizuale të imazhit.

Algoritmet e kompresimit pa humbje

Algoritmi RLE
Të gjithë algoritmet e serisë RLE bazohen në një ide shumë të thjeshtë: grupet përsëritëse të elementeve zëvendësohen nga një çift (numri i përsëritjeve, elementi përsëritës). Le ta shqyrtojmë këtë algoritëm në shembullin e një sekuence bitash. Në këtë sekuencë, grupet e zeros dhe njësh do të alternohen. Për më tepër, në grupe shpesh do të ketë më shumë se një element. Pastaj sekuenca 11111 000000 11111111 00 do të korrespondojë me grupin e mëposhtëm të numrave 5 6 8 2. Këta numra tregojnë numrin e përsëritjeve (numërimi fillon nga njësh), por edhe këta numra duhet të kodohen. Ne do të supozojmë se numri i përsëritjeve qëndron në intervalin nga 0 në 7 (d.m.th., 3 bit do të jenë të mjaftueshëm që ne të kodojmë numrin e përsëritjeve). Pastaj sekuenca e konsideruar më sipër është koduar nga sekuenca e mëposhtme e numrave 5 6 7 0 1 2. Është e lehtë të llogaritet se 21 bit janë të nevojshëm për të koduar sekuencën origjinale, dhe në të ngjeshur Metoda RLE formë, kjo sekuencë zë 18 bit.
Edhe pse ky algoritëm është shumë i thjeshtë, efikasiteti i tij është relativisht i ulët. Për më tepër, në disa raste, aplikimi i këtij algoritmi nuk çon në një ulje, por në një rritje të gjatësisë së sekuencës. Për shembull, merrni parasysh sekuencën e mëposhtme 111 0000 11111111 00. Sekuenca përkatëse RL duket kështu: 3 4 7 0 1 2. Gjatësia e sekuencës origjinale është 17 bit, gjatësia e sekuencës së ngjeshur është 18 bit.
Ky algoritëm është më efikas për imazhet bardh e zi. Gjithashtu përdoret shpesh si një nga fazat e ndërmjetme të kompresimit të algoritmeve më komplekse.

Algoritmet e fjalorit

Ideja që qëndron në themel të algoritmeve të fjalorit është se ekziston një kodim i zinxhirëve të elementeve të sekuencës origjinale. Ky kodim përdor një fjalor të veçantë, i cili merret në bazë të sekuencës origjinale.
Ekziston një familje e tërë e algoritmeve të fjalorit, por ne do të shqyrtojmë algoritmin më të zakonshëm LZW, të quajtur sipas zhvilluesve të tij Lepel, Ziv dhe Welch.
Fjalori në këtë algoritëm është një tabelë që është e mbushur me zinxhirë kodues ndërsa algoritmi funksionon. Kur deshifroni kodin e ngjeshur, fjalori rikthehet automatikisht, kështu që nuk ka nevojë të transferoni fjalorin së bashku me kodin e ngjeshur.
Fjalori inicializohet me të gjitha vargjet e vetme, d.m.th. rreshtat e parë të fjalorit paraqesin alfabetin në të cilin po kodojmë. Kërkimet e kompresimit për zinxhirin më të gjatë të regjistruar tashmë në fjalor. Sa herë që haset një varg që nuk është shkruar ende në fjalor, ai shtohet atje dhe shfaqet një kod i ngjeshur që korrespondon me vargun e shkruar tashmë në fjalor. Në teori, nuk vendosen kufizime në madhësinë e fjalorit, por në praktikë ka kuptim të kufizohet kjo madhësi, pasi me kalimin e kohës fillojnë të ndodhin zinxhirë që nuk gjenden më në tekst. Përveç kësaj, kur madhësia e tabelës dyfishohet, duhet të ndajmë një bit shtesë për ruajtjen e kodeve të ngjeshur. Për të parandaluar situata të tilla, futet një kod i veçantë, që simbolizon inicializimin e tabelës me të gjithë zinxhirët me një element.
Konsideroni një shembull të kompresimit nga një algoritëm. Ne do të ngjeshim vargun e qyqeve. Supozoni se fjalori do të përmbajë 32 pozicione, që do të thotë se secili prej kodeve të tij do të marrë 5 bit. Fillimisht, fjalori plotësohet me sa vijon:

Kjo tabelë është, si në anën e atij që ngjesh informacionin, ashtu edhe në anën e atij që dekompreson. Tani do të shikojmë procesin e kompresimit.

Tabela tregon procesin e plotësimit të fjalorit. Është e lehtë të llogaritet se kodi i ngjeshur që rezulton merr 105 bit, dhe teksti origjinal (duke supozuar se shpenzojmë 4 bit për kodimin e një karakteri) merr 116 bit.
Në fakt, procesi i dekodimit reduktohet në një dekodim të drejtpërdrejtë të kodeve, ndërkohë që është e rëndësishme që tabela të inicializohet në të njëjtën mënyrë si gjatë kodimit. Tani merrni parasysh algoritmin e deshifrimit.


Vargu i shtuar në fjalor në hapin e i-të mund të përcaktohet plotësisht vetëm në i+1. Natyrisht, rreshti i-të duhet të përfundojë me karakterin e parë të rreshtit i+1. Se. sapo kuptuam se si të rivendosim një fjalor. Me njëfarë interesi është situata kur një sekuencë e formës cScSc është e koduar, ku c është një karakter i vetëm dhe S është një varg, dhe fjala cS është tashmë në fjalor. Në pamje të parë mund të duket se dekoderi nuk do të jetë në gjendje ta zgjidhë këtë situatë, por në fakt të gjitha vargjet e këtij lloji duhet të përfundojnë gjithmonë me të njëjtin karakter me të cilin fillojnë.

Algoritmet e kodimit të entropisë
Algoritmet në këtë seri caktojnë kodin më të shkurtër të ngjeshur për elementët më të shpeshtë të sekuencave. Ato. sekuencat me të njëjtën gjatësi janë të koduara me kode të ngjeshur me gjatësi të ndryshme. Për më tepër, sa më e zakonshme të jetë sekuenca, aq më i shkurtër është kodi i ngjeshur përkatës.
Algoritmi Huffman
Algoritmi Huffman ju lejon të ndërtoni kodet e parashtesave. Ju mund të mendoni për kodet e parashtesave si shtigje drejt pemë binare: kalimi nga një nyje te fëmija i saj i majtë korrespondon me 0 në kod, dhe fëmijës së djathtë - 1. Nëse shënojmë gjethet e pemës me karaktere të koduara, marrim një paraqitje binar të pemës së kodit të prefiksit.
Le të përshkruajmë një algoritëm për ndërtimin e një peme Huffman dhe marrjen e kodeve Huffman.
  1. Karakteret e alfabetit të hyrjes formojnë një listë të nyjeve të lira. Çdo fletë ka një peshë që e barabartë me frekuencën pamja e karakterit
  2. Përzgjidhen dy nyje pemësh të lira me peshën më të vogël
  3. Prindi i tyre krijohet me një peshë të barabartë me peshën e tyre totale
  4. Prindi i shtohet listës së nyjeve të lira dhe dy fëmijët e tij hiqen nga kjo listë.
  5. Njërit hark që del nga prindi i është caktuar biti 1, tjetrit i është caktuar biti 0
  6. Hapat që fillojnë nga e dyta përsëriten derisa të mbetet vetëm një nyje e lirë në listën e nyjeve të lira. Do të konsiderohet rrënja e pemës.
Duke përdorur këtë algoritëm, ne mund të marrim kodet Huffman për një alfabet të caktuar, duke marrë parasysh shpeshtësinë e shfaqjes së karaktereve.
Kodimi aritmetik
Algoritmet e kodimit aritmetik kodojnë vargjet e elementeve në thyesa. Kjo merr parasysh shpërndarjen e frekuencës së elementeve. Për momentin, algoritmet e kodimit aritmetik mbrohen nga patenta, kështu që ne do të shqyrtojmë vetëm idenë kryesore.
Le të përbëhet alfabeti ynë nga N karaktere a1,…,aN dhe frekuencat e shfaqjes së tyre p1,…,pN, përkatësisht. Le të ndajmë intervalin ID e tabelës: 0
64 bajtet e mbetura duhet të plotësojnë tabelën 8x8.



Shikoni më nga afër rendin në të cilin plotësohen vlerat e tabelës. Ky rend quhet rend zigzag:

Shënuesi: SOF0 - DCT bazë

Ky shënues quhet SOF0, që do të thotë se imazhi është i koduar në metodën bazë. Është shumë e zakonshme. Por në internet, metoda progresive që ju njihni nuk është më pak e popullarizuar, kur ngarkohet fillimisht një imazh me rezolucion të ulët dhe më pas një foto normale. Kjo ju lejon të kuptoni se çfarë tregohet atje, pa pritur ngarkesë të plotë. Specifikimi përcakton disa metoda të tjera, më duket, jo shumë të zakonshme.

FF C0 00 11 08 00 10 00 10 03 01 22 00 02
11 01 03 11 01

Gjatësia: 17 bajt.
Saktësia: 8 bit Në metodën bazë, është gjithmonë 8. Siç e kuptoj unë, kjo është thellësia bit e vlerave të kanalit.
Lartësia e figurës: 0x10 = 16
Gjerësia e modelit: 0x10 = 16
Numri i komponentëve: 3. Më shpesh është Y, Cb, Cr.

Komponenti i parë:
ID: 1
Hollimi horizontal (H 1): 2
[_2] Hollimi vertikal (V 1): 2
ID e tabelës së kuantizimit: 0

Komponenti i dytë:
ID: 2
Hollimi horizontal (H 2): 1
[_1] Hollimi vertikal (V 2): 1

Komponenti i tretë:
ID: 3
Hollimi horizontal (H 3): 1
[_1] Hollimi vertikal (V 3): 1
Identifikuesi i tabelës së kuantizimit: 1

Tani shikoni se si të përcaktoni se sa i holluar është një imazh. Ne gjejmë H max \u003d 2 dhe V max \u003d 2. Kanali i do të shkatërrohet me H max /H i herë horizontalisht dhe V max /V i herë vertikalisht.

Shënuesi: DHT (grafiku i Huffman)

Ky seksion ruan kodet dhe vlerat e marra nga kodimi Huffman.

FF C4 00 15 00 01 01 00 00 00 00
00 00 00 00 00 00 00 00 00 00 03 02

gjatësia: 21 bajt.
klasa: 0 (0 - tabela e koeficientit DC, 1 - Tabela e koeficientit AC).
[_0] ID e tabelës: 0
Gjatësia e kodit Huffman: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
Numri i kodeve:
Numri i kodeve nënkupton numrin e kodeve të asaj gjatësi. Vini re se seksioni ruan vetëm gjatësinë e kodeve, jo vetë kodet. Ne duhet t'i gjejmë vetë kodet. Pra, kemi një kod me gjatësi 1 dhe një me gjatësi 2. Gjithsej janë 2 kode, nuk ka më kode në këtë tabelë.
Çdo kod ka një vlerë të lidhur me të, dhe ato janë të renditura më pas në skedar. Vlerat janë me një bajt, kështu që ne lexojmë 2 bajt.
- vlera e kodit të parë.
- vlera e kodit të dytë.

Ndërtimi i një Peme të Kodeve Huffman

Duhet të ndërtojmë një pemë binare nga tabela që morëm në seksionin DHT. Dhe tashmë nga kjo pemë ne do të njohim çdo kod. Vlerat shtohen sipas rendit në të cilin janë renditur në tabelë. Algoritmi është i thjeshtë: pavarësisht se ku jemi, ne gjithmonë përpiqemi të shtojmë një vlerë në degën e majtë. Dhe nëse ajo është e zënë, atëherë në të djathtë. Dhe nëse nuk ka vend atje, atëherë kthehemi në nivelin e mësipërm dhe provojmë nga atje. Duhet të ndaleni në një nivel të barabartë me gjatësinë e kodit. Degët e majta korrespondojnë me vlerën 0, e djathta - 1.
Koment:
Nuk ka nevojë të filloni nga lart çdo herë. Vlera e shtuar - kthehu në nivelin e mësipërm. A ekziston dega e duhur? Nëse po, ngjituni përsëri. Nëse jo, krijoni një degë të duhur dhe shkoni atje. Pastaj, nga atje, filloni të kërkoni për të shtuar vlerën tjetër.

Pemë për të gjitha tabelat në këtë shembull:


UPD (faleminderit): Nyjet e pemës së parë (DC, id =0) duhet të kenë vlerat 0x03 dhe 0x02

Në rrathë - vlerat e kodeve, nën rrathë - vetë kodet (do të shpjegoj se i morëm duke shkuar nga lart në secilën nyje). Është me kode të tilla (të kësaj dhe tabelave të tjera) që vetë përmbajtja e figurës kodohet.

Shënuesi: SOS (Fillimi i Skanimit)

Bajt në shenjë do të thotë "PO! Më në fund, shkuam drejtpërdrejt në analizimin e seksionit të imazhit të koduar! Megjithatë, seksioni quhet simbolikisht SOS.

  FF DA 00 0C 03 01 00 02 11
03 11 00 3F 00

Gjatësia e kokës (jo e gjithë seksionit): 12 bajt.
Numri i komponentëve të skanimit. Kemi 3, nga një për Y, Cb, Cr.

Komponenti i parë:
Numri i komponentit të imazhit: 1 (Y)
ID e tabelës Huffman për koeficientët DC: 0
[_0] ID e tabelës Huffman për koeficientët AC: 0

Komponenti i dytë:
Numri i komponentit të imazhit: 2 (Cb)

[_1]

Komponenti i tretë:
Numri i komponentit të imazhit: 3 (Cr)
ID e tabelës Huffman për koeficientët DC: 1
[_1] ID e tabelës Huffman për koeficientët AC: 1

Këta komponentë alternojnë në mënyrë ciklike.

Këtu përfundon pjesa e kokës, nga këtu deri në fund të të dhënave të koduara (shënues).


0

Gjetja e koeficientit DC.
1. Leximi i një sekuence bitash (nëse takojmë 2 bajt, atëherë ky nuk është një shënues, por vetëm një bajt). Pas çdo bit, ne lëvizim përgjatë pemës Huffman (me identifikuesin përkatës) përgjatë degës 0 ose 1, në varësi të bitit të lexuar. Ne ndalojmë nëse jemi në nyjen përfundimtare.
10 1011101110011101100001111100100

2. Marrim vlerën e nyjës. Nëse është e barabartë me 0, atëherë koeficienti është 0, shkruajeni atë në tabelë dhe vazhdoni me leximin e koeficientëve të tjerë. Në rastin tonë - 02. Kjo vlerë është gjatësia e koeficientit në bit. Kjo do të thotë, ne lexojmë 2 bitet e ardhshme, ky do të jetë koeficienti.
10 10 11101110011101100001111100100

3. Nëse shifra e parë e vlerës në paraqitjen binar është 1, atëherë lëreni atë siç është: DC_coef = vlera. Përndryshe, konverto: DC_coef = vlera-2 gjatësia e vlerës +1 . Ne shkruajmë koeficientin në tabelë në fillim të zigzagut - këndi i sipërm i majtë.

Gjetja e koeficientëve AC.
1. Ngjashëm me pikën 1, gjetja e koeficientit DC. Ne vazhdojmë të lexojmë sekuencën:
10 10 1110 1110011101100001111100100

2. Marrim vlerën e nyjës. Nëse është e barabartë me 0, do të thotë që vlerat e mbetura të matricës duhet të plotësohen me zero. Pastaj matrica tjetër është e koduar. Të parët që lexojnë deri në këtë pikë dhe më kanë shkruar për këtë në një personal, do të marrin një plus në karma. Në rastin tonë, vlera e nyjës është 0x31.
Thithja e parë: 0x3 - ja sa zero duhet të shtojmë në matricë. Këta janë 3 koeficientë zero.
Thithja e dytë: 0x1 - gjatësia e koeficientit në bit. Lexoni pjesën tjetër.
10 10 1110 1 110011101100001111100100

3. Ngjashëm me pikën 3 të gjetjes së koeficientit DC.

Siç e keni kuptuar tashmë, ju duhet të lexoni koeficientët AC derisa të pengoheni në vlerën zero të kodit, ose derisa matrica të mbushet.
Në rastin tonë, ne do të marrim:
10 10 1110 1 1100 11 101 10 0 0 0 1 11110 0 100
dhe matrica:





A keni vënë re se vlerat janë të mbushura në të njëjtin model zigzag?
Arsyeja e përdorimit të këtij rendi është e thjeshtë - pasi sa më të mëdha të jenë vlerat e v dhe u, aq më pak i rëndësishëm ka koeficienti S vu në transformimin kosinus diskret. Prandaj, në raportet e larta të kompresimit, koeficientët e parëndësishëm vendosen në zero, duke zvogëluar kështu madhësinë e skedarit.

[-4 1 1 1 0 0 0 0] [ 5 -1 1 0 0 0 0 0]
[ 0 0 1 0 0 0 0 0] [-1 -2 -1 0 0 0 0 0]
[ 0 -1 0 0 0 0 0 0] [ 0 -1 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [-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 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]

[-4 2 2 1 0 0 0 0]
[-1 0 -1 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 0 0 0 0 0]

Oh, harrova të them se koeficientët e koduar DC nuk janë vetë koeficientët DC, por dallimet e tyre midis koeficientëve të tabelës së mëparshme (të të njëjtit kanal)! Ju duhet të rregulloni matricat:
DC për të 2-tën: 2 + (-4) = -2
DC për të tretën: -2 + 5 = 3
DC për të katërtën: 3 + (-4) = -1

[-2 1 1 1 0 0 0 0] [ 3 -1 1 0 0 0 0 0] [-1 2 2 1 0 0 0 0]
………

Tani porositni. Ky rregull është i vlefshëm deri në fund të skedarit.

… dhe sipas matricës për Cb dhe Cr:

[-1 0 0 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 0 0 0 0 0]

Meqenëse ka vetëm një matricë secila, koeficientët DC mund të lihen të paprekur.

Informatikë

Kuantizimi

A ju kujtohet se matrica kalon në fazën e kuantizimit? Elementet e matricës duhet të shumëzohen term pas termi me elementët e matricës së kuantizimit. Mbetet për të zgjedhur atë të duhurin. Së pari, ne skanuam komponentin e parë, komponentin e tij të imazhit = 1. Komponenti i imazhit me këtë ID përdor një matricë kuantizimi prej 0 (e kemi të parën nga dy). Pra, pas shumëzimit:


[ 0 120 280 0 0 0 0 0]
[ 0 -130 -160 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]

Në mënyrë të ngjashme, marrim 3 matrica të tjera të kanalit Y ...

[-320 110 100 160 0 0 0 0] [ 480 -110 100 0 0 0 0 0]
[ 0 0 140 0 0 0 0 0] [-120 -240 -140 0 0 0 0 0]
[ 0 -130 0 0 0 0 0 0] [ 0 -130 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [-140 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 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]

[-160 220 200 160 0 0 0 0]
[-120 0 -140 0 0 0 0 0]
[-140 -130 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 0 0 0 0 0]

… dhe me matricë për Cb dhe Cr.

[-170 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
[ 180 210 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 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 0 0 0 0] [ 0 0 0 0 0 0 0 0]

Transformimi i kosinusit diskret të anasjelltë

Formula nuk duhet të jetë e vështirë*. S vu është matrica jonë e koeficientit që rezulton. u - kolonë, v - rresht. s yx - vlerat e drejtpërdrejta të kanalit.

* Në përgjithësi, kjo nuk është plotësisht e vërtetë. Kur arrita të deshifroja dhe shfaqja një vizatim 16x16 në ekran, bëra një imazh 600x600 (nga rruga, ky ishte kopertina e albumit tim të preferuar Mind.In.A.Box - Lost Alone). Nuk funksionoi menjëherë - u shfaqën defekte të ndryshme. Së shpejti mund të admiroja foton e ngarkuar saktë. I vetmi zhgënjim ishte shpejtësia e shkarkimit. E mbaj mend akoma se u deshën 7 sekonda. Por kjo nuk është për t'u habitur, nëse përdorni pa menduar formulën e mësipërme, atëherë për të llogaritur një kanal prej një piksel, duhet të gjeni 128 kosinus, 768 shumëzime dhe disa shtesa atje. Vetëm mendoni për këtë - pothuajse një mijë operacione të vështira për vetëm një kanal prej një piksel! Për fat të mirë, ka vend për optimizim (pas shumë eksperimentesh, e reduktova kohën e ngarkimit në kufirin e saktësisë së kohëmatësit prej 15 ms, dhe pas kësaj e ndryshova imazhin në një foto 25 herë më të madhe. Ndoshta do të shkruaj për këtë në një artikull të veçantë) .

Do të shkruaj rezultatin e llogaritjes vetëm të matricës së parë të kanalit Y (vlerat janë të rrumbullakosura):


[ 87 72 50 36 37 55 79 95]
[-10 5 31 56 71 73 68 62]
[-87 -50 6 56 79 72 48 29]

Dhe 2 të tjerat:
Cb Cr
[ 60 52 38 20 0 -18 -32 -40] [ 19 27 41 60 80 99 113 120]
[ 48 41 29 13 -3 -19 -31 -37] [ 0 6 18 34 51 66 78 85]
[ 25 20 12 2 -9 -19 -27 -32] [-27 -22 -14 -4 7 17 25 30]
[ -4 -6 -9 -13 -17 -20 -23 -25] [-43 -41 -38 -34 -30 -27 -24 -22]
[ -37 -35 -33 -29 -25 -21 -18 -17] [-35 -36 -39 -43 -47 -51 -53 -55]
[ -67 -63 -55 -44 -33 -22 -14 -10] [ -5 -9 -17 -28 -39 -50 -58 -62]
[ -90 -84 -71 -56 -39 -23 -11 -4] [ 32 26 14 -1 -18 -34 -46 -53]
[-102 -95 -81 -62 -42 -23 -9 -1] [ 58 50 36 18 -2 -20 -34 -42]

  1. Oh, le të shkojmë të hamë!
  2. Po unë nuk hyj fare, për çfarë po flisni.
  3. Pasi të merren vlerat e ngjyrave YCbCr, mbetet të konvertohet në RGB, si kjo: YCbCrToRGB(Y ij , Cb ij , Cr ij) , Y ij , Cb ij , Cr ij - matricat tona të marra.
  4. 4 matrica Y, dhe nga një Cb dhe Cr secila, pasi holluam kanalet dhe 4 pikselë Y korrespondojnë me një Cb dhe Cr secila. Prandaj, llogaritni kështu: YCbCrToRGB(Y ij , Cb , Cr )
Nëse keni zgjedhur 1 dhe 4, atëherë unë jam i lumtur për ju. Ose e keni kuptuar mirë, ose së shpejti do të shijoni ushqimin.

YCbCr në RGB

R = Y + 1,402 * Kr
G = Y - 0,34414 * Cb - 0,71414 * Cr
B = Y + 1,772 * Cb
Mos harroni të shtoni 128 secila. Nëse vlerat shkojnë përtej intervalit, atëherë caktoni vlerat kufitare. Formula është e thjeshtë, por gjithashtu ha një pjesë të kohës së procesorit.

Këtu janë tabelat që rezultojnë për kanalet R, G, B për katrorin e sipërm majtas 8x8 të shembullit tonë:
255 248 194 148 169 215 255 255
255 238 172 115 130 178 255 255
255 208 127 59 64 112 208 255
255 223 143 74 77 120 211 255
237 192 133 83 85 118 184 222
177 161 146 132 145 162 201 217
56 73 101 126 144 147 147 141
0 17 76 126 153 146 127 108

231 185 117 72 67 113 171 217
229 175 95 39 28 76 139 189
254 192 100 31 15 63 131 185
255 207 115 46 28 71 134 185
255 241 175 125 112 145 193 230
226 210 187 173 172 189 209 225
149 166 191 216 229 232 225 220
72 110 166 216 238 231 206 186

255 255 249 203 178 224 255 255
255 255 226 170 140 187 224 255
255 255 192 123 91 138 184 238
255 255 208 139 103 146 188 239
255 255 202 152 128 161 194 232
255 244 215 200 188 205 210 227
108 125 148 172 182 184 172 167
31 69 122 172 191 183 153 134

fund

Në përgjithësi, unë nuk jam një specialist JPEG, kështu që vështirë se mund t'u përgjigjem të gjitha pyetjeve. Pikërisht kur shkruaja dekoderin tim, shpesh më duhej të merresha me probleme të ndryshme të pakuptueshme. Dhe kur imazhi u shfaq gabimisht, nuk e dija se ku bëra një gabim. Ndoshta ai i ka keqinterpretuar pjesët, ose ka përdorur gabimisht DCT. Më ka munguar vërtet një shembull hap pas hapi, kështu që shpresoj se ky artikull do të ndihmojë kur shkruaj një dekoder. Unë mendoj se mbulon përshkrimin e metodës bazë, por ende nuk mund të ia dalësh vetëm me të. Këtu janë disa lidhje që më ndihmuan:

Fotografitë dhe fotografitë ndryshojnë nga njëra-tjetra jo vetëm në përmbajtje, por edhe në karakteristika të tjera "kompjuterike". Për shembull, madhësia.

Ndodh që, duket, dy vizatime identike, por njëra ka një madhësi tre herë më të madhe se tjetra.

Gjithashtu, imazhet ndryshojnë në cilësi. Unë mendoj se ju keni parë foto jashtëzakonisht Cilesi e keqe. Kjo është e dukshme me sy të lirë. Për shembull, dy foto identike, por njëra është me cilësi më të mirë dhe tjetra është me cilësi më të keqe.

Dhe ndodh që fotografisë duket se i mungojnë ngjyrat. Këtu është një shembull.

Dhe formati ose lloji i skedarit është përgjegjës për të gjithë këtë.

Në fakt, imazhet vijnë në një sërë formatesh. Dhe ka shumë, shumë prej tyre. Ne nuk do t'i konsiderojmë të gjitha, por do të flasim për ato më të zakonshmet. Këto janë formate të tilla si bmp, gif, jpg, png, tiff.

Ato ndryshojnë nga njëri-tjetri, para së gjithash, në cilësi. Dhe cilësia ndryshon në numrin (ngopjen) e ngjyrave.

Për shembull, unë pikturoj një foto duke përdorur ngjyra të ndryshme. Dhe pastaj papritmas disa prej tyre përfunduan, dhe ju duhet të përfundoni pikturën me atë që keni. Sigurisht, do të përpiqem të bëj gjithçka që është e mundur në mënyrë që kjo të mos ndikojë shumë në rezultatin, por prapë fotografia nuk do të dalë ashtu siç do të donim - më e zbehur, e paqartë.

Kështu është me formatet e imazhit. Njëra i lë të gjitha ngjyrat, tjetra këput një pjesë. Dhe, ndonjëherë, për shkak të kësaj, fotografia përkeqësohet.

Ky është një shembull mjaft i vrazhdë. Në fakt, gjithçka është disi më e ndërlikuar atje, por unë mendoj se ju e keni kapur pikën kryesore.

Formatet e zakonshme të imazhit

BMP është një format për vizatimet e bëra në programin Paint. Mund të përdoret për të ruajtur fotografitë e vizatuara në një kompjuter. Por në internet, ky lloj skedari nuk përdoret për shkak të vëllimit të madh. Pra, nëse doni të publikoni një fotografi të vizatuar në Paint në një blog ose rrjet social, ajo duhet të jetë e një lloji tjetër - gif, jpg ose png.

GIF është një format imazhi popullor në internet. Ju mund t'i ruani ato në të pa humbje të cilësisë, por me një numër të kufizuar ngjyrash - 256. GIF ka fituar popullaritet të veçantë për faktin se në të mund të krijoni fotografi të vogla të animuara (lëvizëse).

JPG është një format për foto dhe piktura me shumë ngjyra. Në të, ju mund ta ruani imazhin si pa humbje të cilësisë ashtu edhe me humbje.

PNG është një format modern i imazhit. Përftohet një imazh i këtij lloji madhësia e vogël dhe pa humbje të cilësisë. Shumë i përshtatshëm: skedari është i vogël dhe cilësia është e mirë. Ai gjithashtu mbështet transparencën.

TIFF - imazhe me cilësi shumë të mirë, pa kompresim.Për rrjedhojë, madhësia e skedarëve të tillë është e madhe. TIFF përdoret kur cilësia ka rëndësi. Për shembull, kur krijoni karta biznesi, broshura, kopertina reviste.

Cilin format të zgjidhni

  • BMP - nëse ky është një vizatim i bërë në programin Paint, dhe do ta mbani vetëm në kompjuter.
  • GIF - nëse një animacion ose vizatim me një sasi të vogël ngjyrash për publikim në ueb.
  • PNG - nëse është një vizatim në të cilin ka shumë ngjyra ose disa pjesë transparente.
  • JPG (jpeg) - nëse foto.
  • TIFF - imazh për printim (kartela biznesi, broshura, postera, etj.).

Pershendetje te dashur miq. Sot do të flasim se cili format imazhi është më i mirë për t'u përdorur në sit, cilat formate të skedarëve grafikë janë të disponueshëm për sitin sot dhe nëse është e nevojshme të ndiqni formate të reja grafike.

Kam mjaft pyetje si kjo, shumë nga studentët e mi pyesin nëse mund të përdorin formatet e reja SVG dhe WebP dhe ku është vendi më i mirë për të aplikuar këto imazhe. Sigurisht, mund të përdorni formate të reja, thjesht duhet të kuptoni se cili format është më i përshtatshmi për çfarë.

Deri më sot, imazhet në faqe janë një pjesë integrale. Duke filluar nga dizajn grafik dhe ngarkimi i imazheve në artikuj, grafika shoqëron shumicën e sajteve në ueb. Por bukuria ka një çmim

Imazhet e pa optimizuara janë një nga faktorët që ngadalësojnë faqen, siç tregohet nga shërbimet e verifikimit.

Prandaj, gjithmonë do të përballeni me zgjedhjen se cilin format të zgjidhni për imazhin. Kjo do të varet nga madhësia dhe cilësia e saj. Dhe për të përdorur imazhe më të vogla dhe pa humbje të cilësisë, duhet të dini disa gjëra.

Cilat imazhe uebsajti përdor sot?

Të gjitha imazhet për faqet e internetit ndahen në:

  • raster (shembull - JPG, JPEG, GIF, PNG),
  • vektori (shembull - SVG).

Raster imazhet përbëhen nga pikselë që ruajnë një ngjyrë dhe një vlerë transparence. Këto formate përfshijnë imazhe në artikuj, butona, ikona dhe elementë dizajni. Këto imazhe janë të njohura në mesin e zhvilluesve dhe pronarëve të faqeve të internetit. Disavantazhi kryesor i imazheve raster është se ato nuk shkallëzohen mirë.

Kjo do të thotë, kur madhësia e imazhit rritet, ka një humbje të cilësisë.

Vektor imazhet përbëhen nga vija dhe pika. Informacioni në lidhje me imazhin ruhet në udhëzimet e vizatimit matematikor, i cili ju lejon të shkallëzoni imazhe të tilla sa të doni pa humbur cilësinë.

Të gjitha këto imazhe mund dhe përdoren në faqet moderne të internetit. Thjesht duhet të kuptoni se përpara se të ngarkoni në sit, !

Përshkrimi i formateve të njohura të imazhit për sitin

Nga përshkrimi i këtyre formateve, do të kuptoni se ku dhe çfarë formati përdoret më mirë në faqe.

JPEG

JPEG ose JPG është një nga formatet më të njohura të imazhit për faqet e internetit. Formati mbështet miliona ngjyra, gjë që i jep atij një pozitë udhëheqëse në prezantimin e fotove dhe fotove në faqe.

Imazhet në këtë format janë optimizuar mjaft mirë pa pothuajse asnjë humbje cilësie, gjë që ju lejon të merrni një skedar më të vogël pa humbje të cilësisë vizuale. Duhet mbajtur mend se çdo optimizim i mëpasshëm zvogëlon cilësinë.

Skedarët e këtij formati mbështeten nga të gjitha pajisjet dhe shfletuesit, gjë që konfirmon edhe një herë popullaritetin e saj dhe ju lejon të mos shqetësoheni për problemet e shfaqjes në sajte.

Disavantazhi i madh i këtij formati është mungesa e transparencës. Kjo do të thotë, kombinimi i imazheve në këtë format nuk do të funksionojë. Për detyra të tilla, është më mirë të përdorni formatin e mëposhtëm.

PNG

Ky format përdor një algoritëm kompresimi pa humbje. Për nga numri i ngjyrave dhe niveli i transparencës, është i disponueshëm në dy lloje: 8 dhe 24-bit. Të dyja mbështesin transparencën.

8-bit nuk është shumë popullor, por 24-bit përdoret gjerësisht për të imazhe të ndryshme Online. Për shkak të transparencës, ju lejon të krijoni imazhe të kombinuara. Shpesh përdoret për të krijuar butona të animuar, ikona, ku nevojitet një efekt transparence.

Imazhet PNG mund të optimizohen, modifikohen shumë herë - do të ruajë cilësinë e tij origjinale.

Formati mbështetet gjithashtu nga të gjithë shfletuesit dhe pajisjet, gjë që garanton shfaqjen e tij në çdo ekran.

Cilësia e imazheve duket më e mirë se JPG, por madhësia e skedarit do të jetë më e madhe. Kjo duhet të merret parasysh kur vendosni skedarë në sit.

gif

Është një format 8-bit që mbështet 256 ngjyra, transparencë dhe animacion. Për shkak të mbështetjes së një numri të vogël ngjyrash, madhësia e skedarit është gjithashtu minimale.

Formati nuk është i përshtatshëm për foto dhe imazhe me gamë të gjerë ngjyrat.

Por përdoret gjerësisht kur krijoni banderola, butona, ikona etj.

Në faqet moderne, ky format përdoret gjithnjë e më pak.

Më tej, le të flasim për formatet relativisht të fundit SVG dhe WebP, të cilat nuk janë aq të njohura, por po fitojnë popullaritet dhe mbështetje, dhe janë më të përshtatshmet për kërkesat e shpejtësisë së ngarkimit dhe përshtatshmërisë së faqes.

SVG

Ky është formati skedarët vektoriali bazuar në XML. Formati filloi të fitonte popullaritet mjaft kohët e fundit, pasi më parë ishte mbështetur dobët në shfletues. Dhe për shkak të problemeve të ekranit, askush nuk nxitonte ta përdorte atë.

Sot SVG mbështetet nga të gjithë shfletuesit modernë. Por, problemet e ekranit ende ndodhin.

Ky format përdoret më së shpeshti për imazhe të thjeshta si logot, elementet e dizajnit etj. Nuk aplikohet për fotografi.

Formati SVG është i lehtë, përshtatet mirë për imazhe të qarta në çdo rezolucion ekrani, mbështet animacionin, mund të kontrollohet nëpërmjet CSS dhe të vendoset në HTML, duke zvogëluar numrin e kërkesave.

WebP

Një format me burim të hapur i zhvilluar nga Google posaçërisht për ueb. Sot YouTube përdor konvertimin e fotografive të videove në formatin WebP.

Formati ofron kompresim të shkëlqyer dhe mbështet transparencën. Ai kombinon avantazhet e formateve JPG dhe PNG pa rritur madhësinë e skedarit.

Por, pavarësisht nga avantazhet e formatit, ai nuk mbështetet nga të gjithë shfletuesit, si IE, Edge, Firefox dhe Safari.

Ka mënyra rreth këtyre kufizimeve, por ato parandalojnë që formati të përdoret në mënyrë universale.

konkluzioni

Miq, shpresoj se kam shpjeguar gjithçka qartë, dhe tani ju e dini se cili format imazhi është më i mirë për t'u përdorur në sit, dhe pse nuk insistoj të përdor një format të veçantë, por rekomandoj një qasje të integruar.

Ndoshta kur WebP të fitojë mbështetje të gjerë, ne të gjithë do të kalojmë tek ajo dhe do të zëvendësojmë jpg dhe png në faqet tona.

Le të diskutojmë në komente se çfarë formatesh përdorni në faqet tuaja, çfarë ju pëlqen dhe çfarë nuk ju pëlqen.

Kjo është e gjitha për sot, pres me padurim komentet tuaja.

Sinqerisht, Maxim Zaitsev.

    ME Tre formatet më të njohura të skedarëve janë JPEG, RAW, TIFF. Ndonjëherë mund të dëgjoni mosmarrëveshje midis fotografëve - cili është formati më i mirë i skedarit për fotografinë, në çfarë formati është më mirë të bëni fotografi, sepse kamerat moderne ju lejojnë të bëni fotografi.printime në cilindo nga këto formate, dhe ndonjëherë në disa në të njëjtën kohë!

    Formati i skedarit në të cilin ruhet imazhi është, në fakt, një kompromis i caktuar midis cilësisë së figurës dhe madhësisë së skedarit.

    Ju ndoshta e dini tashmë se një bitmap përbëhet nga pikselë. Mënyra se si organizohet një skedar bitmap dhe si ruan informacionin e pikselit përcakton formatin e skedarit. Cilësia e një imazhi për një skedar bitmap përcaktohet nga dy parametra kryesorë: madhësia e pikselit (d.m.th., numri i përgjithshëm i pikselëve) dhe saktësia e riprodhimit të ngjyrës reale nga ngjyra e pikselit.Është e qartë me madhësinë e pikselit - sa më shumë piksel (ose - sa më "i vogël" piksel), aq më mirë.Dhe saktësia e ngjyrave varet nga numri i ngjyrave për piksel ose thellësia e ngjyrës.

    Thellësia e ngjyrës (cilësia e ngjyrës, thellësia e bitit të imazhit) - sasia e memories në numrin e biteve të përdorura për të ruajtur dhe përfaqësuar ngjyrën kur kodoni një piksel të një imazhi grafike raster ose video. Numri i biteve tregon numrin e gradimeve (hapat tonale) në çdo komponent të ngjyrave, ose, thjesht, numrin e ngjyrave. Shtimi i 1 bit do të thotë shtim i një bit tjetër në kod binar kromatike.

    • Ngjyra binare 1-bit (21 = 2 ngjyra), më së shpeshti e përfaqësuar nga bardh e zi (ose e zezë dhe jeshile)
    • Ngjyra 2-bitëshe (22 = 4 ngjyra) CGA, NeXTstation në shkallë gri
    • 3-bit me ngjyra (23 = 8 ngjyra) shumë kompjuterë personalë të vjetër me dalje televizive
    • Ngjyra 4-bit (24 = 16 ngjyra) njihet si EGA dhe në një masë më të vogël si standardi VGA me rezolucion të lartë
    • Ngjyra 5-bitëshe (25 = 32 ngjyra) Çipa origjinale Amiga
    • Ngjyra 6-bitëshe (26 = 64 ngjyra) Çipa origjinale Amiga
    • Ngjyra 8-bitëshe (28 = 256 ngjyra) Stacione pune të vjetra Unix, VGA me rezolucion të ulët, Super VGA, AGA
    • Ngjyra 12-bitësh (212 = 4096 ngjyra) në disa sisteme Silicon Graphics, sisteme ngjyrash NeXTstation dhe sisteme të modalitetit Amiga HAM.

    Për shembull, ne jemi duke punuar në hapësirën e ngjyrave RGB. Kjo do të thotë se janë tre kanale nga të cilat formohet ngjyra përfundimtare e pikselit: kanali i kuq (Rad), kanali jeshil (Green), kanali blu (Blu). Le të supozojmë se kanalet janë katër-bit. Kjo do të thotë se çdo kanal ka aftësinë për të shfaqur 16 ngjyra. Si rezultat, i gjithë RGB do të jetë 12-bit dhe do të jetë në gjendje të shfaqet

    C=16x16x16=4096 ngjyra

    Thellësia e ngjyrës në këtë rast është 12 bit.

    Kur flasin për RGB 24-bitësh, nënkuptojnë kanale 8-bitësh (256 ngjyra secila) me një numër total opsionesh ngjyrash për piksel

    C=256x256x256=16777216 ngjyra.

    Numri është mbresëlënës. Ky numër ngjyrash për çdo piksel plotëson kërkesat e artistit fotografik më kërkues.

    Pak për vetë formatet.

    Formati TIFF

    TIFF do të thotë "Formati i skedarit të imazhit të etiketuar" dhe është standardi për industrinë e printimit dhe printimit.

    Si rezultat, kjo është ajo që ndodh:

    1. Nëse kamera juaj është aq e thjeshtë sa që shkrep vetëm JPEG dhe ju dëshironi të merrni cilësi maksimale, vendosni madhësinë maksimale dhe kompresimin minimal dhe mos u shqetësoni se nuk keni formate të tjera. Në shumicën e rasteve, imazhi RAW i përpunuar me kujdes përputhet me JPEG të marrë automatikisht nga kamera.

    2. Ndoshta nuk duhet të bëni fotografi në TIFF. Regjistrimi i këtij formati është më i vështirë dhe nuk ka dallim të dukshëm në krahasim me JPEG me cilësi të lartë.

    3. Nëse keni mundësi të bëni fotografi, punoni me të. Do ta ndjeni veten nëse ju përshtatet. Në disa raste, vetëm RAW bën të mundur nxjerrjen e një fotografie unike për zmadhim të lartë të printimit.

    Mbetet një zgjidhje tjetër, mund të thuhet universale. Ekziston një modalitet që ju lejon të merrni korniza në dy formate në të njëjtën kohë: RAW + JPEG. Regjistroni skena të rëndësishme në këtë modalitet. Ruajtja moderne e informacionit dixhital - si kartat e kujtesës ashtu edhe disqet e ngurtë - ju lejon ta bëni këtë. Në këtë rast, ju merrni një JPEG për të përdorur foton menjëherë, pa shpenzuar kohë për rishikim. Dhe, nëse keni nevojë për këtë, besojini skedarin RAW një specialisti për përpunim.

    Foto. Formatet e skedarëve.

    Është e lehtë të llogaritet se një imazh i pakompresuar me ngjyra të plota prej 2000*1000 pikselësh do të jetë rreth 6 megabajt në madhësi. Nëse flasim për imazhe të marra nga kamerat profesionale ose skanerët me rezolucion të lartë, atëherë madhësia e tyre mund të jetë edhe më e madhe. Megjithë rritjen e shpejtë të kapacitetit të pajisjeve të ruajtjes, algoritme të ndryshme të kompresimit të imazhit janë ende shumë të rëndësishme.
    Të gjithë algoritmet ekzistuese mund të ndahen në dy klasa të mëdha:

    • Algoritmet e kompresimit pa humbje;
    • Algoritmet e kompresimit me humbje.
    Kur flasim për kompresim pa humbje, nënkuptojmë se ekziston një algoritëm i kundërt me algoritmin e kompresimit që ju lejon të rivendosni me saktësi imazhin origjinal. Nuk ka asnjë algoritëm të kundërt për algoritmet e kompresimit me humbje. Ekziston një algoritëm që rikthen një imazh që nuk përputhet domosdoshmërisht saktësisht me origjinalin. Algoritmet e kompresimit dhe rikuperimit zgjidhen për të arritur një shkallë të lartë kompresimi duke ruajtur cilësinë vizuale të imazhit.

    Algoritmet e kompresimit pa humbje

    Algoritmi RLE
    Të gjithë algoritmet e serisë RLE bazohen në një ide shumë të thjeshtë: grupet përsëritëse të elementeve zëvendësohen nga një çift (numri i përsëritjeve, elementi përsëritës). Le ta shqyrtojmë këtë algoritëm në shembullin e një sekuence bitash. Në këtë sekuencë, grupet e zeros dhe njësh do të alternohen. Për më tepër, në grupe shpesh do të ketë më shumë se një element. Pastaj sekuenca 11111 000000 11111111 00 do të korrespondojë me grupin e mëposhtëm të numrave 5 6 8 2. Këta numra tregojnë numrin e përsëritjeve (numërimi fillon nga njësh), por edhe këta numra duhet të kodohen. Ne do të supozojmë se numri i përsëritjeve qëndron në intervalin nga 0 në 7 (d.m.th., 3 bit do të jenë të mjaftueshëm që ne të kodojmë numrin e përsëritjeve). Pastaj sekuenca e konsideruar më sipër kodohet nga sekuenca e mëposhtme e numrave 5 6 7 0 1 2. Është e lehtë të llogaritet se për të koduar sekuencën origjinale kërkohen 21 bit dhe në formën e ngjeshur nga metoda RLE kjo sekuencë merr 18 bit .
    Edhe pse ky algoritëm është shumë i thjeshtë, efikasiteti i tij është relativisht i ulët. Për më tepër, në disa raste, aplikimi i këtij algoritmi nuk çon në një ulje, por në një rritje të gjatësisë së sekuencës. Për shembull, merrni parasysh sekuencën e mëposhtme 111 0000 11111111 00. Sekuenca përkatëse RL duket kështu: 3 4 7 0 1 2. Gjatësia e sekuencës origjinale është 17 bit, gjatësia e sekuencës së ngjeshur është 18 bit.
    Ky algoritëm është më efikas për imazhet bardh e zi. Gjithashtu përdoret shpesh si një nga fazat e ndërmjetme të kompresimit të algoritmeve më komplekse.

    Algoritmet e fjalorit

    Ideja që qëndron në themel të algoritmeve të fjalorit është se ekziston një kodim i zinxhirëve të elementeve të sekuencës origjinale. Ky kodim përdor një fjalor të veçantë, i cili merret në bazë të sekuencës origjinale.
    Ekziston një familje e tërë e algoritmeve të fjalorit, por ne do të shqyrtojmë algoritmin më të zakonshëm LZW, të quajtur sipas zhvilluesve të tij Lepel, Ziv dhe Welch.
    Fjalori në këtë algoritëm është një tabelë që është e mbushur me zinxhirë kodues ndërsa algoritmi funksionon. Kur deshifroni kodin e ngjeshur, fjalori rikthehet automatikisht, kështu që nuk ka nevojë të transferoni fjalorin së bashku me kodin e ngjeshur.
    Fjalori inicializohet me të gjitha vargjet e vetme, d.m.th. rreshtat e parë të fjalorit paraqesin alfabetin në të cilin po kodojmë. Kërkimet e kompresimit për zinxhirin më të gjatë të regjistruar tashmë në fjalor. Sa herë që haset një varg që nuk është shkruar ende në fjalor, ai shtohet atje dhe shfaqet një kod i ngjeshur që korrespondon me vargun e shkruar tashmë në fjalor. Në teori, nuk vendosen kufizime në madhësinë e fjalorit, por në praktikë ka kuptim të kufizohet kjo madhësi, pasi me kalimin e kohës fillojnë të ndodhin zinxhirë që nuk gjenden më në tekst. Përveç kësaj, kur madhësia e tabelës dyfishohet, duhet të ndajmë një bit shtesë për ruajtjen e kodeve të ngjeshur. Për të parandaluar situata të tilla, futet një kod i veçantë, që simbolizon inicializimin e tabelës me të gjithë zinxhirët me një element.
    Konsideroni një shembull të kompresimit nga një algoritëm. Ne do të ngjeshim vargun e qyqeve. Supozoni se fjalori do të përmbajë 32 pozicione, që do të thotë se secili prej kodeve të tij do të marrë 5 bit. Fillimisht, fjalori plotësohet me sa vijon:

    Kjo tabelë është, si në anën e atij që ngjesh informacionin, ashtu edhe në anën e atij që dekompreson. Tani do të shikojmë procesin e kompresimit.


    Tabela tregon procesin e plotësimit të fjalorit. Është e lehtë të llogaritet se kodi i ngjeshur që rezulton merr 105 bit, dhe teksti origjinal (duke supozuar se shpenzojmë 4 bit për kodimin e një karakteri) merr 116 bit.
    Në fakt, procesi i dekodimit reduktohet në një dekodim të drejtpërdrejtë të kodeve, ndërkohë që është e rëndësishme që tabela të inicializohet në të njëjtën mënyrë si gjatë kodimit. Tani merrni parasysh algoritmin e deshifrimit.



    Vargu i shtuar në fjalor në hapin e i-të mund të përcaktohet plotësisht vetëm në i+1. Natyrisht, rreshti i-të duhet të përfundojë me karakterin e parë të rreshtit i+1. Se. sapo kuptuam se si të rivendosim një fjalor. Me njëfarë interesi është situata kur një sekuencë e formës cScSc është e koduar, ku c është një karakter i vetëm dhe S është një varg, dhe fjala cS është tashmë në fjalor. Në pamje të parë mund të duket se dekoderi nuk do të jetë në gjendje ta zgjidhë këtë situatë, por në fakt të gjitha vargjet e këtij lloji duhet të përfundojnë gjithmonë me të njëjtin karakter me të cilin fillojnë.

    Algoritmet e kodimit të entropisë
    Algoritmet në këtë seri caktojnë kodin më të shkurtër të ngjeshur për elementët më të shpeshtë të sekuencave. Ato. sekuencat me të njëjtën gjatësi janë të koduara me kode të ngjeshur me gjatësi të ndryshme. Për më tepër, sa më e zakonshme të jetë sekuenca, aq më i shkurtër është kodi i ngjeshur përkatës.
    Algoritmi Huffman
    Algoritmi Huffman ju lejon të ndërtoni kode prefikse. Ne mund të mendojmë për kodet e parashtesave si shtigje në një pemë binare: kalimi nga një nyje në fëmijën e saj të majtë korrespondon me 0 në kod dhe fëmijës së saj të djathtë korrespondon me 1. Nëse shënojmë gjethet e pemës me karaktere të koduara, marrim një paraqitje binar të pemës së kodit të prefiksit.
    Le të përshkruajmë një algoritëm për ndërtimin e një peme Huffman dhe marrjen e kodeve Huffman.
  1. Karakteret e alfabetit të hyrjes formojnë një listë të nyjeve të lira. Çdo fletë ka një peshë që është e barabartë me shpeshtësinë e shfaqjes së simbolit
  2. Përzgjidhen dy nyje pemësh të lira me peshën më të vogël
  3. Prindi i tyre krijohet me një peshë të barabartë me peshën e tyre totale
  4. Prindi i shtohet listës së nyjeve të lira dhe dy fëmijët e tij hiqen nga kjo listë.
  5. Njërit hark që del nga prindi i është caktuar biti 1, tjetrit i është caktuar biti 0
  6. Hapat që fillojnë nga e dyta përsëriten derisa të mbetet vetëm një nyje e lirë në listën e nyjeve të lira. Do të konsiderohet rrënja e pemës.
Duke përdorur këtë algoritëm, ne mund të marrim kodet Huffman për një alfabet të caktuar, duke marrë parasysh shpeshtësinë e shfaqjes së karaktereve.
Kodimi aritmetik
Algoritmet e kodimit aritmetik kodojnë vargjet e elementeve në thyesa. Kjo merr parasysh shpërndarjen e frekuencës së elementeve. Për momentin, algoritmet e kodimit aritmetik mbrohen nga patenta, kështu që ne do të shqyrtojmë vetëm idenë kryesore.
  • tutorial


Ju e kuptuat saktë nga titulli se ky nuk është përshkrimi mjaft i zakonshëm i algoritmit JPEG (e përshkrova formatin e skedarit në detaje në artikullin "Dekodimi JPEG për Dummies"). Para së gjithash, mënyra e zgjedhur e paraqitjes së materialit supozon se nuk dimë asgjë jo vetëm për JPEG, por edhe për transformimin Fourier dhe kodimin Huffman. Në përgjithësi, ne mbajmë mend pak nga ligjëratat. Ata sapo bënë një foto dhe filluan të mendojnë se si mund të kompresohet. Prandaj, u përpoqa të shpreh vetëm thelbin në një mënyrë të arritshme, por në të cilën lexuesi do të zhvillojë një kuptim mjaft të thellë dhe, më e rëndësishmja, intuitiv i algoritmit. Formulat dhe llogaritjet matematikore - në minimum, vetëm ato që janë të rëndësishme për të kuptuar se çfarë po ndodh.

Njohja e algoritmit JPEG është shumë e dobishme për më shumë sesa thjesht kompresim imazhi. Ai përdor teorinë e përpunimi dixhital sinjalet, analizat matematikore, algjebra lineare, teoria e informacionit, në veçanti, transformimi i Furierit, kodimi pa humbje, etj. Prandaj, njohuritë e marra mund të jenë të dobishme kudo.

Nëse ka një dëshirë, atëherë unë sugjeroj të kaloni të njëjtat hapa vetë paralelisht me artikullin. Kontrolloni se për çfarë mase arsyetimi i mësipërm është i përshtatshëm imazhe të ndryshme, përpiquni të bëni modifikimet tuaja në algoritëm. Është shumë interesante. Si një mjet, unë mund të rekomandoj një pako të mrekullueshme Python + NumPy + Matplotlib + PIL (jastëk). Pothuajse e gjithë puna ime (përfshirë grafikën dhe animacionin) është bërë me to.

Kujdes trafiku! Shumë ilustrime, grafikë dhe animacione (~ 10 Mb). Për ironi, në artikullin për JPEG ka vetëm 2 imazhe me këtë format nga pesëdhjetë.

Cilido qoftë algoritmi për kompresimin e informacionit, parimi i tij do të jetë gjithmonë i njëjtë - gjetja dhe përshkrimi i modeleve. Sa më shumë modele, aq më shumë tepricë, aq më pak informacion. Arkivuesit dhe koduesit zakonisht "mprehen" për një lloj informacioni specifik, dhe ata e dinë se ku t'i gjejnë ato. Në disa raste, modeli është menjëherë i dukshëm, për shembull, një fotografi e një qielli blu. Çdo rresht i paraqitjes së tij dixhitale mund të përshkruhet mjaft saktë nga një vijë e drejtë.

Ne do të stërvitemi me macet rakun. Imazhi gri i mësipërm është marrë si shembull. Kombinon mirë si zonat homogjene ashtu edhe ato të kundërta. Dhe nëse mësojmë të ngjeshim gri, atëherë nuk do të ketë probleme me ngjyrën.

Paraqitja vektoriale

Së pari, le të kontrollojmë se sa të varur janë dy pikselët fqinjë. Është logjike të supozohet se ka shumë të ngjarë që ato të jenë shumë të ngjashme. Le ta kontrollojmë këtë për të gjitha çiftet e imazhit. Ne i shënojmë ato në planin koordinativ me pika në mënyrë që vlera e pikës përgjatë boshtit X të jetë vlera e pikselit të parë, përgjatë boshtit Y - i dyti. Për imazhin tonë 256 x 256, marrim 256*256/2 piksele:


Në mënyrë të parashikueshme, shumica e pikave janë në ose afër vijës y=x (dhe ka edhe më shumë prej tyre sesa mund të shihni në figurë, pasi ato mbivendosen shumë herë me njëra-tjetrën dhe, për më tepër, janë të tejdukshme). Dhe nëse po, do të ishte më e lehtë për të punuar duke i kthyer ato 45 °. Për ta bërë këtë, ju duhet t'i shprehni ato në një sistem tjetër koordinativ.


Vektorët bazë të sistemit të ri janë padyshim si më poshtë: . Detyrohet të ndahet me rrënjën e dy për të marrë një sistem ortonormal (gjatësitë e vektorëve bazë janë të barabarta me një). Këtu tregohet se një pikë p = (x, y) në sistemin e ri do të paraqitet si një pikë (a 0 , a 1). Duke ditur koeficientët e rinj, ne mund t'i marrim lehtësisht të vjetrit me rrotullim të kundërt. Natyrisht, koordinata e parë (e re) është mesatarja, dhe e dyta është diferenca midis x dhe y (por e ndarë me rrënjën e 2). Imagjinoni që ju kërkohet të lini vetëm njërën nga vlerat: ose 0 ose 1 (d.m.th., vendosni tjetrën në zero). Është më mirë të zgjidhni një 0, pasi vlera e një 1 dhe kështu ka të ngjarë të jetë rreth zeros. Ja çfarë ndodh nëse e rivendosim imazhin vetëm nga 0:


Zmadhimi 4 herë:


Ky lloj kompresimi nuk është shumë mbresëlënës, për të qenë i sinqertë. Është më mirë që në mënyrë të ngjashme ta ndani figurën në treshe pikselësh dhe t'i paraqisni ato në hapësirën tredimensionale.

Është e njëjta tabelë, por nga këndvështrime të ndryshme. Vijat e kuqe janë akset që sugjerojnë veten. Ato i përgjigjen vektorëve: . Ju kujtoj se ju duhet të pjesëtoni me disa konstante në mënyrë që gjatësitë e vektorëve të bëhen të barabartë me një. Kështu, duke u zgjeruar mbi një bazë të tillë, marrim 3 vlera a 0, a 1, a 2 dhe një 0 është më e rëndësishme se një 1 dhe një 1 është më e rëndësishme se një 2. Nëse hedhim një 2, atëherë grafiku do të "rrafshohet" në drejtim të vektorit e 2 . Kjo fletë tashmë mjaft e hollë tre-dimensionale do të bëhet e sheshtë. Nuk do të humbasë shumë, por do të heqim qafe një të tretën e vlerave. Le të krahasojmë imazhet e rivendosura nga treshe: (a 0 , 0, 0), (a 1 , a 2 , 0) dhe (a 0 , a 1 , a 2). NË versioni i fundit nuk hodhëm asgjë, ndaj marrim origjinalin.


Zmadhimi 4 herë:


Vizatimi i dytë tashmë është i mirë. Zonat e mprehta janë zbutur pak, por në përgjithësi fotografia ruhet shumë mirë. Dhe tani, le të ndajmë me katër në të njëjtën mënyrë dhe të përcaktojmë vizualisht bazën në hapësirën katër-dimensionale ... Ah, mirë, po. Por ju mund të merrni me mend se cili do të jetë një nga vektorët bazë, ky është: (1,1,1,1)/2. Prandaj, mund të shikohet projeksioni i hapësirës katërdimensionale në hapësirën pingul me vektorin (1,1,1,1) në mënyrë që të identifikohen të tjerët. Por kjo nuk është mënyra më e mirë.
Qëllimi ynë është të mësojmë se si të transformojmë (x 0 , x 1 , ..., x n-1) në (a 0, a 1, ..., a n-1) në mënyrë që çdo vlerë e a të jetë më e vogël dhe më pak të rëndësishme se të mëparshmet. Nëse mund ta bëjmë këtë, atëherë ndoshta vlerat e fundit të sekuencës mund të hidhen fare. Eksperimentet e mësipërme lënë të kuptohet se është e mundur. Por nuk mund të bëhet pa aparatin matematikor.
Pra, ju duhet të konvertoni pikët në një bazë të re. Por së pari ju duhet të gjeni një bazë të përshtatshme. Le të kthehemi te eksperimenti i parë i çiftëzimit. Le ta konsiderojmë atë në terma të përgjithshëm. Ne kemi përcaktuar vektorët bazë:

Shprehur nëpërmjet tyre vektor fq:

ose në koordinata:

Për të gjetur një 0 dhe një 1 ju duhet të projektoni fqe 0 dhe e 1 respektivisht. Dhe për këtë ju duhet të gjeni produktin skalar

në mënyrë të ngjashme:

Në koordinata:

Shpesh është më i përshtatshëm për të kryer transformimin në formë matrice.

Pastaj A = EX dhe X = E T A. Kjo është një formë e bukur dhe e përshtatshme. Matrica E quhet matricë e transformimit dhe është ortogonale, do ta takojmë më vonë.

Kalimi nga vektorët në funksione.

Është i përshtatshëm për të punuar me vektorë të dimensioneve të vogla. Megjithatë, ne duam të gjejmë modele në blloqe më të mëdha, kështu që në vend të vektorëve N-dimensionale, është më e përshtatshme të operojmë me sekuenca që përfaqësojnë një imazh. Sekuenca të tilla do t'i quaj funksione diskrete, pasi arsyetimi i mëposhtëm vlen edhe për funksionet e vazhdueshme.
Duke iu rikthyer shembullit tonë, imagjinoni një funksion f(i) që përcaktohet vetëm në dy pika: f(0)=x dhe f(1)=y. Në mënyrë të ngjashme, ne përcaktojmë funksionet bazë e 0 (i) dhe e 1 (i) bazuar në bazat e 0 dhe e 1 . Ne marrim:

Ky është një përfundim shumë i rëndësishëm. Tani në togfjalëshin "zgjerimi i një vektori përsa i përket vektorëve ortonormalë" mund të zëvendësojmë fjalën "vektor" me "funksion" dhe të marrim shprehjen plotësisht të saktë "zgjerimi i një funksioni për sa i përket funksioneve ortonormale". Nuk ka rëndësi që kemi marrë një funksion kaq të shkurtër, pasi i njëjti arsyetim funksionon për një vektor N-dimensional, i cili mund të përfaqësohet si një funksion diskret me vlera N. Dhe puna me funksione është më e qartë se sa me vektorë me dimensione N. Ju mund, dhe anasjelltas, të përfaqësoni një funksion të tillë si një vektor. Për më tepër, e zakonshme funksion të vazhdueshëm mund të përfaqësohet si një vektor me dimensione të pafundme, megjithëse jo në hapësirën Euklidiane, por në hapësirën Hilbert. Por ne nuk do të shkojmë atje, do të na interesojnë vetëm funksionet diskrete.
Dhe problemi ynë për të gjetur një bazë kthehet në problemin e gjetjes së një sistemi të përshtatshëm funksionesh ortonormale. Në arsyetimin e mëposhtëm, supozohet se ne kemi përcaktuar disi një grup funksionesh bazë, në kuptim të të cilave do të zgjerojmë.
Le të themi se kemi një funksion (të përfaqësuar, për shembull, me vlera) që duam ta përfaqësojmë si një shumë të të tjerëve. Ju mund ta përfaqësoni këtë proces në formë vektoriale. Për të zgjeruar një funksion, ju duhet ta "projektoni" atë në funksionet bazë një nga një. Në kuptimin vektorial, llogaritja e projeksionit jep konvergjencën minimale të vektorit origjinal me një tjetër në distancë. Duke pasur parasysh se distanca llogaritet duke përdorur teoremën e Pitagorës, atëherë një paraqitje e ngjashme në formën e funksioneve jep përafrimin më të mirë të rrënjës-mesatare-katrore të një funksioni me një tjetër. Kështu, çdo koeficient (k) përcakton "afërsinë" e funksionit. Më formalisht, k*e(x) është përafrimi më i mirë rms me f(x) midis l*e(x).
Shembulli i mëposhtëm tregon procesin e përafrimit të një funksioni me vetëm dy pika. Në të djathtë është paraqitja vektoriale.


Në lidhje me eksperimentin tonë të çiftëzimit, mund të themi se këto dy pika (0 dhe 1 në abshisë) janë një çift pikselësh ngjitur (x, y).
E njëjta gjë, por me animacion:


Nëse marrim 3 pikë, atëherë duhet të kemi parasysh vektorë 3d, por përafrimi do të jetë më i saktë. Dhe për një funksion diskret me vlera N, duhet të merrni parasysh vektorët N-dimensionale.
Duke pasur një grup koeficientësh të marrë, mund të merret lehtësisht funksioni origjinal duke mbledhur funksionet bazë të marra me koeficientët përkatës. Analiza e këtyre koeficientëve mund të japë shumë informacione të dobishme(në varësi të bazës). Një rast i veçantë i këtyre konsideratave është parimi i zgjerimit në një seri Fourier. Në fund të fundit, arsyetimi ynë është i zbatueshëm për çdo bazë, dhe kur zgjerohet në një seri Fourier, merret një krejtësisht specifik.

Transformimet diskrete të Furierit (DFT)

Në pjesën e mëparshme, arritëm në përfundimin se do të ishte mirë ta zbërthejmë funksionin në komponentë. Në fillim të shekullit të 19-të, Fourier gjithashtu mendoi për këtë. Vërtetë, ai nuk kishte një fotografi me një rakun, kështu që ai duhej të hetonte shpërndarjen e nxehtësisë mbi një unazë metalike. Pastaj zbuloi se është shumë e përshtatshme të shprehet temperatura (dhe ndryshimi i saj) në secilën pikë të unazës si një shumë e sinusoideve me periudha të ndryshme. "Fourier vendosi (rekomandoj leximin, interesant) që harmonika e dytë zbërthehet 4 herë më shpejt se e para, dhe harmonikat e rendit më të lartë prishen me një ritëm edhe më të shpejtë."
Në përgjithësi, shpejt doli që funksionet periodike mund të zbërthehen në mënyrë të jashtëzakonshme në një shumë sinusoidësh. Dhe meqenëse në natyrë ka shumë objekte dhe procese të përshkruara nga funksionet periodike, është shfaqur një mjet i fuqishëm për analizën e tyre.
Ndoshta një nga proceset periodike më të dukshme është zëri.

  • Grafiku i parë - një ton i pastër me një frekuencë prej 2500 herc.
  • 2 - zhurma e bardhë. Kjo është, zhurma me frekuenca të shpërndara në mënyrë të barabartë në të gjithë gamën.
  • 3 - shuma e dy të parave.
Nëse do të më jepeshin vlerat e funksionit të fundit në kohën kur nuk dija për seritë Fourier dhe do të më kërkonin t'i analizoja ato, atëherë patjetër që do të isha në humbje dhe nuk do të mund të thoja asgjë të vlefshme. Epo, po, një lloj funksioni, por si ta kuptojmë se ka diçka të porositur atje? Por nëse do të kisha menduar të dëgjoja funksionin e fundit, atëherë veshi do të kishte zënë një ton të pastër mes zhurmës. Edhe pse jo shumë i mirë, pasi kam zgjedhur në mënyrë specifike parametra të tillë gjatë gjenerimit në mënyrë që sinjali të shpërndahet vizualisht në zhurmë në grafikun total. Siç e kuptoj, ende nuk është përcaktuar saktësisht se si Aparat dëgjimi për shurdhët e bën atë. Megjithatë, kohët e fundit është bërë e qartë se ai nuk e zbërthen tingullin në sinusoidë. Ndoshta një ditë do të kuptojmë se si ndodh kjo dhe do të shfaqen algoritme më të avancuara. Epo, ne jemi ende mënyra e modës së vjetër.
Pse të mos provoni të merrni sinusoidet si bazë? Në fakt, ne e kemi bërë tashmë atë. Kujtoni zbërthimin tonë në 3 vektorë bazë dhe paraqitini ato në një grafik:


Po, po, e di që duket si përshtatje, por me tre vektorë është e vështirë të presësh më shumë. Por tani është e qartë se si të merrni, për shembull, 8 vektorë bazë:


Jo mirë kontroll i vështirë tregon se këta vektorë janë pingul në çift, d.m.th., ortogonal. Kjo do të thotë se ato mund të përdoren si bazë. Një transformim mbi një bazë të tillë është i njohur dhe quhet Transformimi Diskret i Kosinusit (DCT). Unë mendoj se është e qartë nga grafikët e mësipërm se si është marrë formula e transformimit DCT:

Është ende e njëjta formulë: A = EX me një bazë të zëvendësuar. Vektorët bazë të DCT të specifikuar (ata janë vektorë rreshtash të matricës E) janë ortogonalë, por jo ortonormalë. Kjo duhet mbajtur mend gjatë transformimit të anasjelltë (nuk do të ndalem në këtë, por, për ata që janë të interesuar, DCT inversi ka një term 0,5*a 0, ​​pasi vektori zero i bazës është më i madh se të tjerët).
Shembulli i mëposhtëm tregon procesin e përafrimit të nëntotaleve me vlerat origjinale. Në çdo përsëritje, baza tjetër shumëzohet me koeficientin tjetër dhe i shtohet shumës së ndërmjetme (d.m.th., në të njëjtën mënyrë si në eksperimentet e hershme në rakun - një e treta e vlerave, dy të tretat).


Por, megjithatë, përkundër disa argumenteve për përshtatshmërinë e zgjedhjes së një baze të tillë, ende nuk ka argumente reale. Në të vërtetë, ndryshe nga zëri, përshtatshmëria e zbërthimit të një imazhi në funksione periodike është shumë më pak e dukshme. Sidoqoftë, imazhi mund të jetë vërtet shumë i paparashikueshëm edhe në një zonë të vogël. Prandaj, fotografia është e ndarë në copa mjaft të vogla, por jo shumë të vogla, që dekompozimi të ketë kuptim. Në JPEG, imazhi "ndahet" në katrorë 8x8. Brenda një pjese të tillë, fotografitë janë zakonisht shumë uniforme: sfondi plus luhatje të lehta. Zona të tilla afrohen në mënyrë elegante nga sinusoidet.
Epo, le të themi se ky fakt është pak a shumë intuitiv. Por ka një ndjenjë të keqe për tranzicionet e mprehta të ngjyrave, sepse ndryshimi i ngadaltë i funksioneve nuk do të na shpëtojë. Duhet të shtojmë funksione të ndryshme me frekuencë të lartë që bëjnë punën e tyre, por shfaqen anash në një sfond homogjen. Le të marrim një imazh 256x256 me dy zona kontrasti:


Ne zbërthejmë çdo rresht duke përdorur DCT, duke marrë kështu 256 koeficientë për rresht.
Pastaj ne lëmë vetëm koeficientët e parë n dhe vendosim pjesën tjetër të barabartë me zero, dhe, për rrjedhojë, imazhi do të përfaqësohet si një shumë e vetëm harmonikave të para:


Numri në foto është numri i gjasave të mbetura. Në imazhin e parë, mbetet vetëm vlera mesatare. Një sinusoid me frekuencë të ulët tashmë i është shtuar të dytit, e kështu me radhë. Nga rruga, kushtojini vëmendje kufirit - pavarësisht nga përafrimi më i mirë, 2 shirita janë qartë të dukshëm pranë diagonales, njëri është më i lehtë, tjetri është më të errët. Një pjesë e imazhit të fundit është zmadhuar 4 herë:

Dhe në përgjithësi, nëse larg nga kufiri shohim sfondin fillestar uniform, atëherë kur i afrohemi, amplituda fillon të rritet, më në fund arrin një vlerë minimale dhe më pas bëhet ashpër maksimumi. Ky fenomen njihet si efekti Gibbs.


Lartësia e këtyre gungave, e cila shfaqet pranë ndërprerjeve të funksionit, nuk do të ulet me rritjen e numrit të termave të funksioneve. Në një transformim diskret, ai zhduket vetëm kur ruhen pothuajse të gjithë koeficientët. Më saktësisht, ajo bëhet e padukshme.
Shembulli i mëposhtëm është plotësisht i ngjashëm me dekompozimin e mësipërm të trekëndëshave, por në një rakun të vërtetë:


Kur studiohet DCT, mund të krijohet përshtypja e gabuar se vetëm koeficientët e parë (me frekuencë të ulët) janë gjithmonë të mjaftueshëm. Kjo është e vërtetë për shumë fotografi, ato vlerat e të cilave nuk ndryshojnë në mënyrë drastike. Sidoqoftë, në kufirin e zonave të kundërta, vlerat do të "kërcejnë" me shpejtësi dhe madje edhe koeficientët e fundit do të jenë të mëdhenj. Pra, kur dëgjoni për vetinë e ruajtjes së energjisë të DCT, merrni parasysh faktin se ajo vlen për shumë lloje sinjalesh që hasni, por jo të gjitha. Si shembull, merrni parasysh se si do të dukej një funksion diskret nëse koeficientët e tij të zgjerimit janë zero, përveç atij të fundit. Këshillë: përfaqësoni zbërthimin në formë vektoriale.
Megjithë mangësitë, baza e përzgjedhur është një nga më të mirat në fotografitë reale. Pak më vonë do të shohim një krahasim të vogël me të tjerët.

DCT kundrejt gjithçkaje tjetër

Kur studiova çështjen e transformimeve ortogonale, atëherë, sinqerisht, nuk isha shumë i bindur nga argumentet se gjithçka përreth është një shumë dridhjet harmonike, kështu që ju duhet t'i zbërtheni fotografitë në sinusoidë. Apo ndoshta disa funksione hapash do të ishin më të përshtatshme? Prandaj, po kërkoja rezultatet e kërkimit mbi optimalitetin e DCT në imazhet reale. Fakti që "Është DCT që gjendet më shpesh në aplikime praktike për shkak të vetive të" densitetit të energjisë "" shkruhet kudo. Kjo veti do të thotë që sasia maksimale e informacionit përmbahet në koeficientët e parë. Dhe pse? Nuk është e vështirë për të kryer një studim: ne armatosemi me një mori fotografish të ndryshme, baza të ndryshme të njohura dhe fillojmë të llogarisim devijimin standard nga imazhi real për një numër të ndryshëm koeficientësh. Gjeta një studim të vogël në artikull (imazhe të përdorura) mbi këtë teknikë. Ai përmban grafikët e varësisë së energjisë së ruajtur nga numri i koeficientëve të parë të zgjerimit në baza të ndryshme. Nëse keni shikuar grafikët, do të shihni se DCT po mban vazhdimisht një vend të nderuar… erm… vendin e 3-të. Si keshtu? Çfarë tjetër është një konvertim KLT? Unë lavdërova DCT, dhe më pas ...
KLT
Të gjitha transformimet përveç KLT janë transformime me bazë konstante. Dhe në KLT (transformimi Karhunen-Loeve) llogaritet baza më optimale për disa vektorë. Ai llogaritet në atë mënyrë që koeficientët e parë të japin gabimin më të vogël rrënjë-mesatar-katror në total për të gjithë vektorët. Ne kryem punë të ngjashme më parë me dorë, duke përcaktuar vizualisht bazën. Në fillim kjo duket si një ide e shëndoshë. Ne, për shembull, mund ta ndajmë imazhin në seksione të vogla dhe të llogarisim një bazë të ndryshme për secilën. Por jo vetëm që duket kujdesi për ruajtjen e kësaj baze, por edhe funksionimi i llogaritjes së tij është mjaft i mundimshëm. Dhe DCT humbet vetëm pak, dhe përveç kësaj, DCT ka algoritme të shpejta të konvertimit.
DFT
DFT (Transformimi Diskret Furier) - transformim diskret Furieri. Ky emër ndonjëherë i referohet jo vetëm një transformimi specifik, por edhe të gjithë klasës së transformimeve diskrete (DCT, DST...). Le të shohim formulën DFT:

Siç mund ta merrni me mend, ky është një transformim ortogonal me një lloj baze komplekse. Meqenëse një formë e tillë komplekse ndodh pak më shpesh se zakonisht, ka kuptim të studiohet derivimi i saj.
Mund të krijohet përshtypja se çdo sinjal i pastër harmonik (me një frekuencë të plotë) në zbërthimin e DCT do të japë vetëm një koeficient jozero që korrespondon me këtë harmonik. Kjo nuk është kështu, sepse përveç frekuencës, është e rëndësishme edhe faza e këtij sinjali. Për shembull, zgjerimi i sinusit në kosinus (në mënyrë të ngjashme në zgjerimin diskret) do të jetë si më poshtë:

Këtu është një harmonikë e pastër për ju. Ajo pjelli një bandë të tjerë. Animacioni tregon koeficientët DCT të një sinusoidi në faza të ndryshme.


Nëse ju dukej se kolonat rrotullohen rreth një boshti, atëherë nuk ju dukej.
Pra, tani ne do ta zbërthejmë funksionin në shumën e sinusoideve jo vetëm frekuenca të ndryshme, por edhe u zhvendos në një fazë. Do të jetë më e përshtatshme të merret në konsideratë zhvendosja e fazës duke përdorur shembullin e një kosinusi:

Një identitet i thjeshtë trigonometrik jep një rezultat të rëndësishëm: zhvendosja e fazës zëvendësohet nga shuma e sinusit dhe kosinusit, marrë me koeficientët cos(b) dhe sin(b). Kjo do të thotë që funksionet mund të zbërthehen në shumën e sinuseve dhe kosinuseve (pa asnjë fazë). Kjo është një formë e zakonshme trigonometrike. Sidoqoftë, kompleksi përdoret shumë më shpesh. Për ta marrë atë, duhet të përdorni formulën Euler. Thjesht zëvendësoni formulat e derivateve për sinusin dhe kosinusin, marrim:


Tani një ndryshim i vogël. Nënvizimi është numri i konjuguar.

Ne marrim barazinë përfundimtare:

c është një koeficient kompleks, pjesa reale e të cilit është e barabartë me koeficientin e kosinusit dhe pjesa imagjinare është e barabartë me koeficientin e sinusit. Dhe grupi i pikave (cos(b), sin(b)) është një rreth. Në një shënim të tillë, çdo harmonik hyn në zgjerim me frekuenca pozitive dhe negative. Prandaj, në formula të ndryshme të analizës Furier, zakonisht ndodh përmbledhja ose integrimi nga minus në plus pafundësi. Shpesh është më i përshtatshëm për të kryer llogaritjet në një formë kaq komplekse.
Transformimi zbërthen sinjalin në harmonikë me frekuenca nga një në N lëkundje në zonën e sinjalit. Por shkalla e kampionimit është N për zonë sinjali. Dhe sipas teoremës së Kotelnikovit (i njohur si teorema Nyquist-Shannon), frekuenca e kampionimit duhet të jetë të paktën dyfishi i frekuencës së sinjalit. Nëse nuk është kështu, atëherë merret efekti i shfaqjes së një sinjali me një frekuencë të rreme:


Vija me pika tregon sinjalin e rindërtuar gabimisht. Këtë fenomen e keni hasur shpesh në jetën tuaj. Për shembull, një lëvizje qesharake e rrotave të një makine në një video, ose një efekt moiré.
Kjo çon në faktin se gjysma e dytë e amplitudave komplekse N duket se përbëhet nga frekuenca të tjera. Këto harmonike false të gjysmës së dytë janë imazh pasqyre së pari dhe mos mbani informacion shtese. Kështu, na mbeten kosinuset N/2 dhe sinuset N/2 (duke formuar një bazë ortogonale).
Mirë, ka një bazë. Përbërësit e tij janë harmonikë me një numër të plotë lëkundjesh në zonën e sinjalit, që do të thotë se vlerat ekstreme të harmonikave janë të barabarta. Më saktësisht, ato janë pothuajse të barabarta, pasi vlera e fundit është marrë jo mjaft nga buza. Për më tepër, çdo harmonik është pothuajse simetrik si pasqyrë në lidhje me qendrën e tij. Të gjitha këto dukuri janë veçanërisht të forta në frekuencave të ulëta, të cilat janë të rëndësishme për ne kur kodojmë. Kjo është gjithashtu e keqe sepse kufijtë e bllokut do të jenë të dukshëm në imazhin e ngjeshur. Unë do të ilustroj bazën DFT me N=8. 2 rreshtat e parë janë përbërës kosinus, të fundit janë sinus:


Vini re pamjen e komponentëve të dyfishtë ndërsa frekuenca rritet.

Ju mund të mendoni mendërisht se si mund të dekompozohet një sinjal, vlerat e të cilit zvogëlohen pa probleme nga vlera maksimale në fillim në vlerën minimale në fund. Një përafrim pak a shumë adekuat mund të bëhet vetëm nga harmonikët drejt fundit, gjë që nuk është shumë e lezetshme për ne. Figura në të majtë është një përafrim i një sinjali me një skaj. Djathtas - simetrike:


E para është jashtëzakonisht e keqe.
Pra, mund të bëhet si në DCT - të zvogëlohen frekuencat me 2 ose një numër tjetër herë, në mënyrë që numri i disa lëkundjeve të jetë i pjesshëm dhe kufijtë të jenë në faza të ndryshme? Atëherë komponentët do të jenë jo ortogonalë. Dhe nuk ka asgjë për të bërë.

DST
Po sikur të përdorim sinuset në vend të kosinuseve në DCT? Ne do të marrim Transformimin Diskret të Sinusit (DST). Por për detyrën tonë, të gjitha ato nuk janë interesante, pasi periudhat e plota dhe gjysma e sinuseve janë afër zeros në kufij. Kjo do të thotë, ne do të marrim afërsisht të njëjtin zbërthim të papërshtatshëm si ai i DFT.
Kthimi në DCT
Si është ai në kufi? Mirë. Ka antifaza dhe nuk ka zero.
Të gjitha të tjerat
Transformimet jo-Furiere. Unë nuk do të përshkruaj.
WHT - matrica përbëhet vetëm nga komponentë hapash me vlera -1 dhe 1.
Haar - transformimi i valëzimit ortogonal me kohë të pjesshme.
Ato janë inferiore ndaj DCT, por më të lehta për t'u llogaritur.

Pra, ju lindi ideja që të krijoni transformimin tuaj. Mbaje mend këte:

  1. Baza duhet të jetë ortogonale.
  2. Me një bazë fikse, nuk mund ta mposhtni KLT-në për sa i përket cilësisë së kompresimit. Ndërkohë, në fotot reale, DCT është pothuajse po aq i mirë.
  3. Në shembullin e DFT dhe DST, duhet të mbani mend për kufijtë.
  4. Dhe mbani mend se DCT ka një avantazh tjetër të mirë - afër kufijve të përbërësve të tyre, derivatet janë të barabartë me zero, që do të thotë se kalimi midis blloqeve fqinje do të jetë mjaft i qetë.
  5. Transformimet Furier kanë algoritme të shpejta me kompleksitet O(N*logN), në ndryshim nga llogaritja në ballë: O(N 2).
Nuk do të jetë e lehtë, apo jo? Megjithatë, për disa lloje imazhesh, mund të zgjidhni një bazë më të mirë se DCT.

transformimet 2D

Tani le të përpiqemi të bëjmë një eksperiment të tillë. Merrni, për shembull, një pjesë të një imazhi.


Grafiku i tij 3D:


Le të kalojmë përmes DCT(N=32) për secilën rresht:


Tani dua që ju t'i drejtoni sytë mbi secilën kolonë të koeficientëve që rezultojnë, d.m.th. nga lart poshtë. Kujtojmë se synimi ynë është të mbajmë sa më pak vlera, duke lënë jashtë ato që nuk kanë rëndësi. Ju ndoshta keni marrë me mend se vlerat e secilës kolonë të koeficientëve të marrë mund të dekompozohen saktësisht në të njëjtën mënyrë si vlerat e imazhit origjinal. Askush nuk na kufizon në zgjedhjen e një matrice transformimi ortogonal, por ne do ta bëjmë atë përsëri duke përdorur DCT(N=8):


Koeficienti (0.0) doli të jetë shumë i madh, kështu që zvogëlohet me 4 herë në grafik.
Pra, çfarë ndodhi?
Këndi i sipërm i majtë është koeficienti më domethënës i zbërthimit të koeficientëve më domethënës.
Këndi i poshtëm i majtë është koeficientët më të parëndësishëm të zgjerimit të koeficientëve më domethënës.
Këndi i sipërm i djathtë është koeficientët më të rëndësishëm të zgjerimit të koeficientëve më të parëndësishëm.
Këndi i poshtëm i djathtë është koeficientët më të parëndësishëm të zgjerimit të koeficientëve më të parëndësishëm.
Është e qartë se rëndësia e koeficientëve zvogëlohet nëse lëvizim diagonalisht nga këndi i sipërm i majtë në këndin e poshtëm djathtas. Dhe cila është më e rëndësishme: (0, 7) apo (7, 0)? Madje çfarë nënkuptojnë?
Së pari sipas rreshtave: A 0 = (EX T) T = XE T (transpozuar, pasi formula A=EX për kolonat), pastaj sipas kolonave: A=EA 0 = EXE T . Nëse llogaritni me kujdes, merrni formulën:

Kështu, nëse vektori zbërthehet në sinusoidë, atëherë matrica në funksione të formës cos(ax)*cos(by). Çdo bllok 8x8 në JPEG përfaqësohet si shuma e 64 funksioneve të formës:


Në Wikipedia dhe burime të tjera, funksione të tilla paraqiten në një formë më të përshtatshme:


Prandaj, koeficientët (0, 7) ose (7, 0) janë po aq të dobishëm.
Sidoqoftë, në fakt, ky është zgjerimi i zakonshëm njëdimensional në 64 baza 64-dimensionale. E gjithë sa më sipër vlen jo vetëm për DCT, por edhe për çdo zbërthim ortogonal. Duke vepruar sipas analogjisë, në rastin e përgjithshëm marrim një transformim ortogonal N-dimensionale.
Dhe këtu është transformimi i rakunit 2D (DCT 256x256). Përsëri me vlera zero. Numrat - numri i koeficientëve jo zero nga të gjithë (vlerat më domethënëse u lanë, të vendosura në zonën trekëndore në këndin e sipërm të majtë).


Mos harroni se koeficienti (0, 0) quhet DC, 63 të tjerët janë AC.

Zgjedhja e madhësisë së bllokut

Shoku pyet: pse përdoret ndarja 8x8 në JPEG. Nga përgjigja e votuar:
DCT e trajton bllokun sikur të ishte periodik dhe duhet të rindërtojë kërcimin që rezulton në kufij. Nëse merrni blloqe 64x64, me shumë mundësi do të keni një kërcim të madh në kufij dhe do t'ju nevojiten shumë komponentë me frekuencë të lartë për ta rindërtuar atë në një saktësi të kënaqshme
Ashtu si, DCT funksionon mirë vetëm në funksione periodike, dhe nëse merrni një madhësi të madhe, ka shumë të ngjarë të merrni një kërcim gjigant në kufijtë e bllokut dhe do t'ju nevojiten shumë komponentë me frekuencë të lartë për ta mbuluar atë. Kjo nuk eshte e vertete! Një shpjegim i tillë është shumë i ngjashëm me DFT, por jo me DCT, pasi mbulon në mënyrë të përsosur kërcime të tilla tashmë me përbërësit e parë.
Në të njëjtën faqe, ka një përgjigje nga MPEG FAQ, me argumentet kryesore kundër blloqeve të mëdha:
  • Pak fitim kur ndaheni në blloqe të mëdha.
  • Rritja e kompleksitetit llogaritës.
  • Probabilitet i lartë një numër i madh skajet e mprehta në një bllok, të cilat do të shkaktojnë efektin Gibbs.
Unë ju sugjeroj ta hulumtoni këtë vetë. Le të fillojmë me së pari.


Në boshtin horizontal - proporcioni i koeficientëve të parë jozero. Vertikale - devijimi standard i pikselëve nga origjinali. Devijimi maksimal i mundshëm merret si një. Sigurisht, një foto nuk mjafton qartë për një vendim. Veç kësaj, nuk po e bëj siç duhet, thjesht po zero. Në një JPEG real, në varësi të matricës së kuantizimit, vetëm vlerat e vogla të përbërësve të frekuencës së lartë zeroohen. Prandaj, eksperimentet dhe përfundimet e mëposhtme synojnë të zbulojnë në mënyrë sipërfaqësore parimet dhe modelet.
Ju mund ta krahasoni ndarjen në blloqe të ndryshme me 25 përqind të mbetur të koeficientëve (nga e majta në të djathtë, pastaj nga e djathta në të majtë):

Blloqet e mëdha nuk tregohen, pasi ato vizualisht pothuajse nuk dallohen nga 32x32. Tani le të shohim ndryshimin absolut me imazhin origjinal (përmirësuar 2 herë, përndryshe asgjë nuk është vërtet e dukshme):

8x8 jep rezultati më i mirë se 4x4. Një rritje e mëtejshme në madhësi nuk ofron më një avantazh qartësisht të dukshëm. Edhe pse do ta konsideroja seriozisht 16x16 në vend të 8x8: një rritje prej 33% e vështirësisë (më shumë për vështirësinë në paragrafin tjetër) jep një përmirësim të vogël, por ende të dukshëm me të njëjtin numër koeficientësh. Sidoqoftë, zgjedhja e 8x8 duket të jetë mjaft e arsyeshme dhe, ndoshta, është mesatarja e artë. JPEG u botua në vitin 1991. Mendoj se një kompresim i tillë ishte shumë i vështirë për procesorët e asaj kohe.

Së dyti argument. Duhet mbajtur mend se me rritjen e madhësisë së bllokut, do të kërkohen më shumë llogaritje. Le të vlerësojmë se si. Kompleksiteti i shndërrimit në ballë, siç dimë ta bëjmë tashmë: O (N 2), pasi çdo koeficient përbëhet nga N terma. Por në praktikë, përdoret një algoritëm efikas i Transformimit të Furierit të Shpejtë (FFT). Përshkrimi i tij është përtej qëllimit të artikullit. Kompleksiteti i tij: O(N*logN). Për një zgjerim dydimensional, duhet ta përdorni dy herë N herë. Pra, kompleksiteti i DCT 2D është O(N 2 logN). Tani le të krahasojmë kompleksitetin e llogaritjes së një imazhi me një bllok dhe disa të vegjël:

  • Në një bllok (kN)x(kN): O((kN) 2 log(kN)) = O(k 2 N 2 log(kN))
  • k*k N*N blloqe: O(k 2 N 2 logN)
Kjo do të thotë që, për shembull, llogaritja kur ndahet në 64x64 është dy herë më e vështirë se në 8x8.

Së treti argument. Nëse kemi një kufi të mprehtë ngjyrash në imazh, atëherë kjo do të ndikojë në të gjithë bllokun. Ndoshta është më mirë që ky bllok të jetë mjaft i vogël, sepse në shumë blloqe fqinje, një kufi i tillë ndoshta nuk do të ekzistojë më. Megjithatë, larg kufijve, zbutja ndodh mjaft shpejt. Përveç kësaj, vetë kufiri do të duket më mirë. Le të kontrollojmë një shembull me një numër të madh të tranzicioneve të kontrastit, përsëri, me vetëm një të katërtën e koeficientëve:


Megjithëse shtrembërimi i bllokut 16x16 shtrihet më tej se 8x8, shkronjat janë më të buta. Prandaj, vetëm dy argumentet e para më bindën. Por më pëlqen më shumë ndarja 16x16.

Kuantizimi

Në këtë fazë, ne kemi një grup matricash 8x8 me koeficientë të transformimit të kosinusit. Është koha për të hequr qafe koeficientët e parëndësishëm. Ekziston një zgjidhje më elegante sesa thjesht rivendosja e koeficientëve të fundit në zero, siç bëmë më lart. Ne nuk jemi të kënaqur me këtë metodë, pasi vlerat jo zero ruhen me saktësi të tepruar, dhe midis atyre që janë të pafat, mund të ketë edhe mjaft të rëndësishme. Rruga për të dalë është përdorimi i një matrice kuantizimi. Humbjet ndodhin në këtë fazë. Çdo koeficient Furier pjesëtohet me numrin përkatës në matricën e kuantizimit. Le të shohim një shembull. Le të marrim bllokun e parë nga rakun tonë dhe ta kuantizojmë atë. Specifikimi JPEG ofron një matricë standarde:


Matrica standarde korrespondon me 50% cilësi në FastStone dhe IrfanView. Një tabelë e tillë u zgjodh për sa i përket balancës së cilësisë dhe raportit të ngjeshjes. Mendoj se vlera për koeficientin DC është më e madhe se ato fqinje për faktin se DCT nuk është normalizuar dhe vlera e parë është më e madhe se sa duhet. Koeficientët e frekuencës së lartë janë ashpërsuar më shumë për shkak të rëndësisë së tyre më të vogël. Unë mendoj se tani matrica të tilla përdoren rrallë, pasi përkeqësimi i cilësisë është qartë i dukshëm. Askush nuk e ndalon përdorimin e tabelës së tyre (me vlera nga 1 në 255)
Kur deshifroni, ndodh procesi i kundërt - koeficientët e kuantizuar shumëzohen term pas termi me vlerat e matricës së kuantizimit. Por meqenëse i kemi rrumbullakosur vlerat, nuk do të jemi në gjendje të rivendosim me saktësi koeficientët origjinal Fourier. Sa më i madh të jetë numri i kuantizimit, aq më i madh është gabimi. Kështu, koeficienti i rikuperuar është vetëm shumëfishi më i afërt.
Një shembull tjetër:

Dhe për ëmbëlsirë, merrni parasysh cilësinë 5% (kur kodoni në Fast Stone).


Kur e rivendosim këtë bllok, do të marrim vetëm vlerën mesatare plus gradientin vertikal (për shkak të vlerës së ruajtur -1). Por vetëm dy vlera ruhen për të: 7 dhe -1. Me blloqet e tjera, situata nuk është më e mirë, këtu është fotografia e restauruar:

Nga rruga, rreth 100% cilësi. Siç mund ta merrni me mend, në këtë rast matrica e kuantizimit përbëhet tërësisht nga ato, domethënë, nuk ndodh kuantizimi. Megjithatë, për shkak të rrumbullakimit të koeficientëve në numrin e plotë më të afërt, ne nuk mund ta rivendosim saktësisht imazhin origjinal. Për shembull, rakun ruajti saktësisht 96% të pikselëve dhe 4% ndryshonte me 1/256. Natyrisht, "shtrembërime" të tilla nuk mund të shihen vizualisht.
Dhe mund të shikoni matricat e kuantizimit të kamerave të ndryshme.

Kodimi

Përpara se të vazhdojmë, duhet të kuptojmë, duke përdorur shembuj më të thjeshtë, se si mund të kompresojmë vlerat e marra.

Shembulli 0(për ngrohje)
Imagjinoni një situatë ku shoku juaj harroi një copë letër me një listë në shtëpinë tuaj dhe tani ju kërkon ta diktoni atë përmes telefonit (nuk ka mënyra të tjera komunikimi).
Listë:

  • d9rg3
  • wfr43gt
  • wfr43gt
  • d9rg3
  • d9rg3
  • d9rg3
  • wfr43gt
  • d9rg3
Si do ta lehtësoni detyrën tuaj? Ju nuk keni ndonjë dëshirë të veçantë për t'i diktuar me dhimbje të gjitha këto fjalë. Por janë vetëm dy prej tyre dhe ato përsëriten. Prandaj, ju thjesht i diktoni disi dy fjalët e para dhe bini dakord që më tej do të quani "d9rg3" fjalën e parë dhe "wfr43gt" të dytën. Atëherë do të jetë e mjaftueshme për të diktuar: 1, 2, 2, 1, 1, 1, 2, 1.

Ne do të caktojmë fjalë të tilla si A, B, C... dhe do t'i quajmë simbole. Për më tepër, çdo gjë mund të fshihet nën simbol: një shkronjë e alfabetit, një fjalë ose një hipopotam në një kopsht zoologjik. Gjëja kryesore është që të njëjtat simbole korrespondojnë me të njëjtat koncepte, dhe të ndryshme - të ndryshme. Meqenëse detyra jonë është kodimi efikas (kompresimi), ne do të punojmë me bit, pasi këto janë njësitë më të vogla të paraqitjes së informacionit. Prandaj, ne e shkruajmë listën si ABBAAABA. Në vend të "fjalës së parë" dhe "fjalës së dytë", mund të përdoren bitet 0 dhe 1. Më pas ABBAAABA kodohet si 01100010 (8 bit = 1 bajt).

Shembulli 1
Kodoni ABC.
3 karaktere të ndryshme (A, B, C) nuk mund të krahasohen me 2 vlera të mundshme bit (0 dhe 1). Dhe nëse po, atëherë mund të përdorni 2 bit për karakter. Për shembull:

  • A:00
  • b: 01
  • C: 10
Sekuenca e biteve të lidhur me një simbol do të quhet kod. ABC do të kodohet si kjo: 000110.

Shembulli 2
Kodoni AAAAAABC.
Përdorimi i 2 bit për karakterin A duket pak i kotë. Po sikur të provoni kështu:

  • C:00

Sekuenca e koduar: 000000100.
Natyrisht, ky opsion nuk është i përshtatshëm, pasi nuk është e qartë se si të deshifrohen dy bitet e para të kësaj sekuence: si AA apo si C? Përdorimi i një lloji ndarës midis kodeve është shumë i kotë, ne do të mendojmë se si ta kapërcejmë këtë pengesë në një mënyrë tjetër. Pra, dështimi është sepse kodi C fillon me kodin A. Por ne jemi të vendosur të kodojmë A me një bit, edhe nëse B dhe C janë dy. Bazuar në këtë dëshirë, ne i japim A-së kodin 0. Atëherë kodet B dhe C nuk mund të fillojnë me 0. Por ato mund të fillojnë me 1:
  • B: 10
  • C: 11

Sekuenca do të kodohet si kjo: 0000001011. Mundohuni ta deshifroni mendërisht. Ju mund ta bëni këtë vetëm në një mënyrë.
Ne kemi zhvilluar dy kërkesa për kodim:
  1. Sa më e madhe të jetë pesha e një karakteri, aq më i shkurtër duhet të jetë kodi i tij. Dhe anasjelltas.
  2. Për dekodim të paqartë, një kod karakteri nuk mund të fillojë me ndonjë kod tjetër karakteri.
Natyrisht, rendi i personazheve nuk është i rëndësishëm, ne jemi të interesuar vetëm për shpeshtësinë e shfaqjes së tyre. Prandaj, çdo karakter shoqërohet me një numër të caktuar, të quajtur peshë. Pesha e karakterit mund të jetë vlerë relative, që pasqyron pjesën e shfaqjes së tij, dhe absolute, e barabartë me numrin e karaktereve. Gjëja kryesore është që peshat duhet të jenë proporcionale me shfaqjen e personazheve.

Shembulli 3
Merrni parasysh rastin e përgjithshëm për 4 karaktere me çdo peshë.

  • A: pa
  • B: pb
  • C: pc
  • D: pd
Pa humbur përgjithësimin, vendosim pa ≥ pb ≥ pc ≥ pd. Ekzistojnë vetëm dy opsione që janë thelbësisht të ndryshme në kodet e gjatësisë:


Cila është e preferueshme? Për ta bërë këtë, duhet të llogaritni gjatësinë e marrë të mesazheve të koduara:
W1 = 2*pa + 2*pb + 2*pc + 2*pd
W2 = pa + 2 * pb + 3 * pc + 3 * pd
Nëse W1 është më pak se W2 (W1-W2<0), то лучше использовать первый вариант:
W1-W2 = pa - (pc+pd)< 0 =>pa< pc+pd.
Nëse C dhe D ndodhin së bashku më shpesh se të tjerët, atëherë kulmi i tyre i përbashkët merr kodin më të shkurtër një-bit. Përndryshe, një bit shkon te karakteri A. Kjo do të thotë se bashkimi i personazheve sillet si një karakter i pavarur dhe ka një peshë të barabartë me shumën e karaktereve hyrëse.
Në përgjithësi, nëse p është pesha e një karakteri të përfaqësuar nga një pjesë e shfaqjes së tij (midis 0 dhe 1), atëherë gjatësia më e mirë e kodit është s=-log 2 p.
Konsideroni atë rast i thjeshtë(mund të përfaqësohet lehtësisht si një pemë). Pra, duhet të kodojmë 2 s karaktere me pesha të barabarta (1/2 s). Për shkak të barazisë së peshave, gjatësitë e kodeve do të jenë të njëjta. Çdo personazh do të ketë nevojë për bit. Pra, nëse pesha e një karakteri është 1/2 s, atëherë gjatësia e tij është s. Nëse pesha zëvendësohet me p, atëherë marrim gjatësinë e kodit s=-log 2 p. Kjo do të thotë që nëse një karakter shfaqet dy herë më rrallë se një tjetër, atëherë gjatësia e kodit të tij do të jetë një bit më e gjatë. Sidoqoftë, një përfundim i tillë është i lehtë për t'u nxjerrë nëse mbani mend se shtimi i një biti ju lejon të dyfishoni numrin e opsioneve të mundshme.
Dhe një vëzhgim tjetër - dy personazhet me peshën më të ulët kanë gjithmonë më të lartën, por gjatësi të barabarta kodet. Për më tepër, pjesët e tyre, përveç të fundit, janë të njëjta. Nëse kjo nuk do të ishte e vërtetë, atëherë të paktën një kod mund të shkurtohej me 1 bit pa shkelur prefiksin. Kjo do të thotë që dy karakteret me peshën më të vogël në pemën e kodit kanë një prind të përbashkët një nivel më të lartë. Ju mund ta shihni këtë në C dhe D më lart.

Shembulli 4
Le të përpiqemi të zgjidhim shembullin e mëposhtëm, sipas përfundimeve të marra në shembullin e mëparshëm.

  1. Të gjithë personazhet janë renditur në rend zbritës të peshave.
  2. Dy personazhet e fundit kombinohen në një grup. Këtij grupi i caktohet një peshë e barabartë me shumën e peshave të këtyre elementeve. Ky grup merr pjesë në algoritëm së bashku me simbolet dhe grupet e tjera.
Hapat përsëriten derisa të mbetet vetëm një grup. Në secilin grup, një karakteri (ose nëngrupi) i është caktuar biti 0 dhe biti tjetër 1.
Ky algoritëm quhet kodim Huffman.
Ilustrimi tregon një shembull me 5 karaktere (A: 8, B: 6, C: 5, D: 4, E: 3). Në të djathtë është pesha e simbolit (ose grupit).

Kodimi i koeficientëve

Ne kthehemi. Tani kemi shumë blloqe me nga 64 koeficientë secili, të cilët duhen ruajtur disi. Zgjidhja më e thjeshtë është përdorimi i një numri fiks të biteve për faktor - padyshim për të ardhur keq. Le të ndërtojmë një histogram të të gjitha vlerave të marra (d.m.th., varësia e numrit të koeficientëve nga vlera e tyre):


Ju lutemi vini re - shkalla është logaritmike! A mund të shpjegoni arsyen e akumulimit të vlerave që tejkalojnë 200? Këta janë koeficientë DC. Meqenëse ato janë shumë të ndryshme nga pjesa tjetër, nuk është për t'u habitur që ato janë të koduara veçmas. Këtu janë vetëm DC:


Vini re se forma e grafikut i ngjan formës së grafikëve nga eksperimentet e hershme të çiftimit dhe triadimit të pikselëve.
Në përgjithësi, vlerat e koeficientëve DC mund të ndryshojnë nga 0 në 2047 (më saktë -1024 në 1023, pasi JPEG zbret 128 nga të gjitha vlerat origjinale, që korrespondon me zbritjen e 1024 nga DC) dhe shpërndahet mjaft në mënyrë të barabartë me maja të vogla. . Pra, kodimi i Huffman nuk do të ndihmojë shumë këtu. Imagjinoni gjithashtu sa e madhe do të jetë pema e kodimit! Dhe gjatë dekodimit, do të duhet të kërkoni vlera në të. Kjo është shumë e kushtueshme. Mendojmë më tej.
Koeficienti DC - vlera mesatare e bllokut 8x8. Le të imagjinojmë një tranzicion gradient (megjithëse jo ideal), i cili shpesh gjendet në fotografi. Vetë vlerat DC do të jenë të ndryshme, por ato do të përfaqësojnë një progresion aritmetik. Prandaj, ndryshimi i tyre do të jetë pak a shumë konstant. Le të ndërtojmë një histogram të dallimeve:


Tani kjo është më mirë, sepse vlerat përgjithësisht përqendrohen rreth zeros (por përsëri, algoritmi Huffman do të japë një pemë tepër të madhe). Vlerat e vogla (sipas vlere absolute) janë të zakonshme, të mëdha janë të rralla. Dhe meqenëse vlerat e vogla zënë pak bit (nëse zerat kryesore hiqen), një nga rregullat e kompresimit është përmbushur mirë: caktoni simbole me pesha të mëdha kode të shkurtra(dhe anasjelltas). Ne jemi ende të kufizuar nga mospërmbushja e një rregulli tjetër: pamundësia e dekodimit të paqartë. Në përgjithësi, ky problem zgjidhet në mënyrat e mëposhtme: ngatërrohuni me kodin ndarës, tregoni gjatësinë e kodit, përdorni kodet e prefiksit (ju tashmë i dini ato - ky është rasti kur asnjë kod nuk fillon me një tjetër). Le të shkojmë me opsionin e dytë të thjeshtë, d.m.th., çdo koeficient (më saktë, ndryshimi midis atyre fqinjëve) do të shkruhet si më poshtë: (gjatësia) (vlera), sipas një pllake të tillë:


Kjo do të thotë, vlerat pozitive kodohen drejtpërdrejt nga përfaqësimi i tyre binar, dhe vlerat negative kodohen në të njëjtën mënyrë, por me 1 kryesore të zëvendësuar me 0. Mbetet të vendoset se si të kodohen gjatësitë. Meqenëse ka 12 vlera të mundshme, 4 bit mund të përdoren për të ruajtur gjatësinë. Por këtu është më mirë të përdorni kodimin Huffman.


Ka më shumë vlera me gjatësi 4 dhe 6, kështu që ata morën kodet më të shkurtra (00 dhe 01).


Mund të lindë pyetja: pse, në shembull, vlera 9 ka kodin 1111110, dhe jo 1111111? Në fund të fundit, a mund ta ngrini me siguri "9" në një nivel më të lartë, pranë "0"? Fakti është se në JPEG nuk mund të përdorni një kod që përbëhet vetëm nga njësi - një kod i tillë është i rezervuar.
Ekziston edhe një veçori tjetër. Kodet e marra nga algoritmi i përshkruar Huffman mund të mos përputhen me bitet me kodet në JPEG, megjithëse gjatësia e tyre do të jetë e njëjtë. Duke përdorur algoritmin Huffman, përftohen gjatësitë e kodeve dhe gjenerohen vetë kodet (algoritmi është i thjeshtë - ato fillojnë me kode të shkurtra dhe i shtojnë ato një nga një në pemë sa më shumë që të jetë e mundur në të majtë, duke ruajtur prefiksin pronë). Për shembull, për pemën e mësipërme, ruhet një listë: 0,2,3,1,1,1,1,1. Dhe, natyrisht, ruhet një listë vlerash: 4,6,3,5,7,2,8,1,0,9. Kur deshifroni, kodet gjenerohen në të njëjtën mënyrë.

Tani porositni. Ne kuptuam se si ruhen DC-të:
[Kodi Huffman për gjatësinë e ndryshimit DC (në bit)]
ku ndryshim DC = rrymë DC - DC e mëparshme

Shikoni AC:


Meqenëse grafiku është shumë i ngjashëm me grafikun për dallimet DC, parimi është i njëjtë: [Kodi Huffman për gjatësinë AC (në bit)]. Por jo në të vërtetë! Meqenëse shkalla në grafik është logaritmike, nuk vërehet menjëherë se ka rreth 10 herë më shumë vlera zero se vlerat 2 - tjetra në frekuencë. Kjo është e kuptueshme - jo të gjithë i mbijetuan kuantizimit. Le të kthehemi te matrica e vlerave të marra në hapin e kuantizimit (duke përdorur matricën e kuantizimit FastStone, 90%).

Meqenëse ka shumë grupe zerosh të njëpasnjëshme, lind ideja - të shënohet vetëm numri i zerave në grup. Ky algoritëm kompresimi quhet RLE (Run-length encoding, repetition encoding). Mbetet për të zbuluar drejtimin e anashkalimit të "duke shkuar me radhë" - kush është pas kujt? Shkrimi nga e majta në të djathtë dhe nga lart poshtë nuk është shumë efikas, pasi koeficientët jo zero janë të përqendruar pranë këndit të sipërm të majtë, dhe sa më afër këndit të poshtëm të djathtë, aq më shumë zero.


Prandaj, JPEG përdor një urdhër të quajtur "Zig-zag" siç tregohet në figurën e majtë. Kjo metodë përzgjedh mirë grupet e zerove. Në figurën e duhur - një mënyrë alternative e anashkalimit, jo e lidhur me JPEG, por me një emër kureshtar (provë). Mund të përdoret në MPEG kur kompresohet video e ndërthurur. Zgjedhja e algoritmit të anashkalimit nuk ndikon në cilësinë e imazhit, por mund të rrisë numrin e grupeve zero të koduara, gjë që përfundimisht mund të ndikojë në madhësinë e skedarit.
Le të modifikojmë hyrjen tonë. Për çdo koeficient AC jo zero:
[Numri i zeros para AC][Kodi Huffman për gjatësinë AC (në bit)]
Unë mendoj se ju do të thoni menjëherë - numri i zerave është gjithashtu i koduar në mënyrë të përsosur nga Huffman! Kjo është një përgjigje shumë e afërt dhe jo e keqe. Por ju mund të optimizoni pak. Imagjinoni që kemi një koeficient AC, para të cilit kishte 7 zero (sigurisht, nëse shkruhej në një rend zigzag). Ato zero janë fryma e vlerave që nuk i mbijetuan kuantizimit. Me shumë mundësi, edhe koeficienti ynë është goditur keq dhe është bërë i vogël, që do të thotë se gjatësia e tij është e shkurtër. Prandaj, numri i zerove para AC dhe gjatësia e AC janë sasi të varura. Prandaj, shkruhet kështu:
[Kodi Huffman për (Numri i zerave para AC, gjatësia e AC (në bit)]
Algoritmi i kodimit mbetet i njëjtë: ato çifte (numri i zerave para AC, gjatësia e AC) që ndodhin shpesh do të marrin kode të shkurtra dhe anasjelltas.

Ne ndërtojmë një histogram të varësisë së sasisë nga këto çifte dhe një pemë Huffman.


"Razma malore" e gjatë konfirmon supozimin tonë.

Karakteristikat e zbatimit në JPEG:
Një çift i tillë zë 1 bajt: 4 bit për numrin e zerove dhe 4 bit për gjatësinë e AC. 4 bit janë vlera nga 0 në 15. AC është më se e mjaftueshme për gjatësinë, por mund të ketë më shumë se 15 zero, apo jo? Pastaj përdoren më shumë çifte. Për shembull, për 20 zero: (15, 0) (5, AC). Kjo do të thotë, zeroja e 16-të është e koduar si një koeficient jo zero. Meqenëse fundi i bllokut është gjithmonë plot zero, çifti (0,0) përdoret pas koeficientit të fundit jozero. Nëse ndodh gjatë dekodimit, atëherë vlerat e mbetura janë të barabarta me 0.

Zbulova se çdo bllok i koduar ruhet në skedar si kjo:
[Kodi Huffman për gjatësinë e ndryshimit DC]
[kodi Huffman për (numri i zerave para AC 1 , gjatësia AC 1 ]

[kodi i Huffman për (numri i zerave para AC n , gjatësia e AC n ]
Ku AC i janë koeficientë AC jo zero.

imazh me ngjyra

Mënyra se si paraqitet një imazh me ngjyra varet nga modeli i zgjedhur i ngjyrave. Zgjidhja e thjeshtë është përdorimi i RGB dhe kodimi i secilit kanal me ngjyra imazhe veç e veç. Atëherë kodimi nuk do të ndryshojë nga kodimi i imazhit gri, vetëm 3 herë më shumë punë. Por kompresimi i imazhit mund të rritet nëse kujtojmë se syri është më i ndjeshëm ndaj ndryshimeve në shkëlqim sesa ngjyra. Kjo do të thotë që ngjyra mund të ruhet me më shumë humbje sesa shkëlqim. RGB nuk ka një kanal të veçantë ndriçimi. Varet nga shuma e vlerave të secilit kanal. Prandaj, kubi RGB (kjo është një paraqitje e të gjitha vlerave të mundshme) thjesht "vendoset" në diagonale - sa më i lartë, aq më i ndritshëm. Por ato nuk kufizohen vetëm në këtë - kubi shtypet pak nga anët, dhe rezulton më shumë si një paralelipiped, por kjo është vetëm për të marrë parasysh tiparet e syrit. Për shembull, ai është më i hapur ndaj ngjyrës së gjelbër sesa blu. Kështu lindi modeli YCbCr.


(Imazhi nga Intel.com)
Y është komponenti i ndriçimit, Cb dhe Cr janë komponentët e ndryshimit të ngjyrave blu dhe të kuqe. Prandaj, nëse duan të kompresojnë imazhin më fort, atëherë RGB konvertohet në YCbCr dhe kanalet Cb dhe Cr hollohen. Kjo do të thotë, ato ndahen në blloqe të vogla, për shembull 2x2, 4x2, 1x2, dhe të gjitha vlerat e një blloku janë mesatare. Ose, me fjalë të tjera, zvogëloni madhësinë e imazhit për këtë kanal me 2 ose 4 herë vertikalisht dhe/ose horizontalisht.


Çdo bllok 8x8 është i koduar (DCT + Huffman) dhe sekuencat e koduara janë shkruar në këtë mënyrë:

Shtë kureshtare që specifikimi JPEG nuk kufizon zgjedhjen e modelit, domethënë, zbatimi i koduesit mund ta ndajë në mënyrë arbitrare imazhin në përbërës me ngjyra (kanale) dhe secila do të ruhet veçmas. Jam i vetëdijshëm për përdorimin e Grayscale (1 kanal), YCbCr (3), RGB (3), YCbCrK (4), CMYK (4). Tre të parat mbështeten pothuajse nga të gjithë, por ka probleme me 4-kanalet e fundit. FastStone, GIMP i mbështesin ato në mënyrë korrekte dhe të rregullt programet e Windows, paint.net nxjerr saktë të gjithë informacionin, por më pas hidh kanalin e 4-të të zi, kështu që (Antelle tha që nuk e hedhin jashtë, lexoni komentet e tij) tregoni një imazh më të lehtë. Majtas - klasik YCbCr JPEG, djathtas CMYK JPEG:



Nëse ato ndryshojnë në ngjyra, ose vetëm një fotografi është e dukshme, atëherë ka shumë të ngjarë që ju keni IE (ndonjë version) (UPD. në komente thonë "ose Safari"). Mund të provoni ta hapni artikullin në shfletues të ndryshëm.

Dhe një gjë tjetër

Me pak fjalë për veçoritë shtesë.
mënyrë progresive
Le t'i zbërthejmë tabelat e fituara të koeficientëve DCT në shumën e tabelave (si kjo (DC, -19, -22, 2, 1) = (DC, 0, 0, 0, 0) + (0, -20, -20 , 0, 0) + (0, 1, -2, 2, 1)). Së pari, ne kodojmë të gjithë termat e parë (siç kemi mësuar tashmë: Huffman dhe bypass zigzag), pastaj të dytat, etj. Ky truk është i dobishëm për internetin e ngadaltë, pasi në fillim ngarkohen vetëm koeficientët DC, të cilët përdoren për të ndërtuar një foto e përafërt me 8x8 "pikselë". Pastaj rrumbullakosni koeficientët AC për të rafinuar modelin. Pastaj korrigjime të përafërta të tyre, pastaj ato më të sakta. Epo, e kështu me radhë. Koeficientët janë të rrumbullakosur, pasi saktësia nuk është aq e rëndësishme në fazat e hershme të ngarkimit, por rrumbullakimi ka një efekt pozitiv në gjatësinë e kodeve, pasi çdo fazë përdor tabelën e vet Huffman.
Modaliteti pa humbje
Kompresim pa humbje. DCT nuk është. Përdoret parashikimi i pikës së 4-të nga tre fqinjë. Gabimet e parashikimit janë të koduara nga Huffman. Për mendimin tim, përdoret pak më shpesh se kurrë.
Mënyra hierarkike
Shtresa të shumta krijohen nga imazhi. leje të ndryshme. Shtresa e parë e trashë kodohet si zakonisht, dhe më pas vetëm ndryshimi (përsosja e imazhit) midis shtresave (pretendohet të jetë një valë valësh Haar). DCT ose Lossless përdoret për kodim. Per mendimin tim perdoret pak me pak se kurre.
Kodimi aritmetik
Algoritmi Huffman krijon kode optimale sipas peshës së karaktereve, por kjo është e vërtetë vetëm për një korrespondencë fikse të karaktereve me kodet. Aritmetika nuk ka një lidhje kaq të ngurtë, e cila lejon përdorimin e kodeve, si të thuash, me një numër të pjesshëm të biteve. Pretendohet se zvogëlon madhësinë e skedarit me një mesatare prej 10% në krahasim me Huffman. Jo e zakonshme për shkak të çështjeve të patentave, nuk mbështetet nga të gjithë.

Shpresoj që tani ta kuptoni algoritmin JPEG në mënyrë intuitive. Faleminderit per leximin!

UPD
vanwin ofroi të tregonte softuerin e përdorur. Kam kënaqësinë të njoftoj se të gjitha janë në dispozicion dhe pa pagesë:

  • Python + NumPy + Matplotlib + PIL (jastëk). Mjeti kryesor. Gjetur me emetimin e "Matlab free alternative". Unë rekomandoj! Edhe nëse nuk jeni të njohur me Python, atëherë në disa orë do të mësoni se si të bëni llogaritjet dhe të ndërtoni grafikë të bukur.
  • jpeg snoop. Tregon informacion të detajuar në lidhje me skedarin jpeg.
  • yEd. Redaktori i grafikut.
  • inkscape. Unë bëra ilustrime në të, të tilla si një shembull i algoritmit Huffman. Kam lexuar disa mësime dhe ka qenë e mrekullueshme.
  • Redaktori i Ekuacionit Daum. Po kërkoja një redaktues formule vizuale, pasi nuk jam shumë miqësor me Latex. Daum Equation është një shtojcë për Chrome, e pashë shumë të përshtatshme. Përveç goditjes së miut, ju mund të modifikoni Latex.
  • gur i shpejte. Nuk mendoj se ka nevojë të prezantohet.
  • PicPick. Alternativë falas për SnagIt. Ulet në tabaka, fotografon atë që thonë aty ku thonë. Plus të gjitha llojet e të mirave, të tilla si një vizore, pipetë, goniometër, etj.

Etiketa: Shtoni etiketa

“Zbatimi i Algoritmeve

JPEG dhe JPEG2000"

E përfunduar:

grupi i nxënësve 819

Ugarov Dmitry

Si funksionojnë algoritmet JPEG dhe JPEG2000

1. Algoritmi JPEG

JPEG (English Joint Photographic Experts Group - një grup i përbashkët ekspertësh në fushën e fotografisë) - është një metodë e përdorur gjerësisht për ngjeshjen e imazheve fotografike. Formati i skedarit që përmban të dhëna të kompresuara zakonisht quhet edhe emri JPEG; shtesat më të zakonshme për skedarë të tillë janë .jpeg, .jfif, .jpg, .JPG ose .JPE. Megjithatë, nga këto, .jpg është zgjerimi më i popullarizuar në të gjitha platformat.

Algoritmi JPEG është një algoritëm kompresimi me humbje të cilësisë.

Zona e aplikimit

Formati është një format kompresimi me humbje, kështu që është e gabuar të supozohet se JPEG ruan të dhënat si 8 bit për kanal (24 bit për pixel). Nga ana tjetër, meqenëse të dhënat po kompresohen nga Formati JPEG dhe të dhënat e dekompresuara zakonisht përfaqësohen në 8 bit për kanal, kjo terminologji përdoret ndonjëherë. Mbështetet gjithashtu kompresimi i imazheve bardh e zi në shkallë gri.

Kur ruani një skedar JPEG, mund të specifikoni shkallën e cilësisë dhe rrjedhimisht shkallën e kompresimit, e cila zakonisht vendoset në disa njësi arbitrare, për shembull, nga 1 në 100 ose nga 1 në 10. Një numër më i madh korrespondon me cilësi më të mirë , por madhësia e skedarit rritet. Zakonisht, ndryshimi në cilësi midis 90 dhe 100 praktikisht nuk perceptohet nga syri. Duhet mbajtur mend se imazhi i restauruar pak nga pak ndryshon gjithmonë nga origjinali. Një keqkuptim i zakonshëm është se cilësi jpeg identike me pjesën e informacionit të ruajtur.

Fazat e kodimit

Procesi i kompresimit JPEG përfshin një numër hapash:

1. Konvertimi i imazhit në hapësirën optimale të ngjyrave;

Në rast aplikimi hapësirë ​​ngjyrash ndriçimi/krominanca (YCbCr) arrin raportin më të mirë të kompresimit. Në këtë fazë të kodimit, duke përdorur raportet e duhura, modeli i ngjyrave RGB konvertohet në YCbCr:

Y = 0,299*R + 0,587*G + 0,114*B

Cb = - 0,1687*R – 0,3313*G + 0,5*B

Cr = 0,5*R – 0,4187*G – 0,0813*B.
Gjatë dekodimit, mund të përdoret transformimi i duhur i kundërt:
R = Y + 1,402*Kr

G = Y – 0,34414*Cb – 0,71414*Cr

B = Y + 1,772*Cb.
Shënim në lidhje me Y, Cb, Cr në sistemin vizual të njeriut:

Syri, veçanërisht retina, ka dy lloje qelizash si analizues vizual: qelizat e shikimit të natës që perceptojnë vetëm nuancat e grisë (nga e bardha e ndritshme në të zezën e errët) dhe qelizat e shikimit të ditës që perceptojnë ngjyrën. Qelizat e para që japin ngjyrën RGB zbulojnë një nivel ndriçimi të ngjashëm me vlerën Y. Qelizat e tjera përgjegjëse për perceptimin e nuancës së ngjyrës përcaktojnë vlerën që lidhet me ndryshimin e ngjyrës.


2. Nën kampionimi i komponentëve të krominancës sipas grupeve mesatare të pikselëve;

Pjesa më e madhe e informacionit vizual ndaj të cilit syri i njeriut është më i ndjeshëm përbëhet nga komponentët me ndriçim të shkallës gri (Y) me frekuencë të lartë të hapësirës së ngjyrave YCbCr. Dy komponentët e tjerë të kromatikitetit (Cb dhe Cr) përmbajnë informacione ngjyrash me frekuencë të lartë ndaj të cilave syri i njeriut është më pak i ndjeshëm. Prandaj, një pjesë e caktuar e tij mund të hidhet poshtë dhe, në këtë mënyrë, është e mundur të zvogëlohet numri i pikselëve të konsideruar për kanalet me ngjyra.

1) lloji 4:2:0 (kur imazhi ndahet në katrorë 2x2 pikselë dhe në secilën prej tyre të gjithë pikselët marrin të njëjtat vlera të kanaleve Cb dhe Cr, dhe shkëlqimi Y y mbetet i ndryshëm për secilin)

2) lloji 4:2:2 (bashkimi sipas përbërësve kromatikë ndodh vetëm horizontalisht në grupe prej dy pikselësh).

3) Lloji 4:4:4 nënkupton që çdo piksel në çdo rresht ka vlerën e vet unike të komponentëve Y, Cb dhe Cr. (Fig. 1 a)

4) lloji 4:2:2. Duke nënmostruar sinjalin e krominancës me një faktor 2 horizontalisht, marrim një rrjedhë YCbCr 4:2:2 nga një rrjedhë YCbCr 4:4:4. Hyrja "4: 2: 2" do të thotë që në një rresht të vetëm ka 4 vlera të shkëlqimit për 2 vlera të krominancës (shih Fig. 1 b). Sinjali 4:2:2 YCbCr humbet shumë pak në cilësinë e imazhit ndaj sinjalit YCbCr 4:4:4, por gjerësia e brezit të kërkuar zvogëlohet me 33% të origjinalit.

3. Aplikimi i transformimeve diskrete të kosinusit për të reduktuar tepricën e të dhënave të imazhit;

Faza kryesore e algoritmit është transformimi diskret i kosinusit (DCT ose DCT), i cili është një lloj transformimi Furier. Përdoret kur punoni me imazhe për qëllime të ndryshme, jo vetëm për qëllime kompresimi. Kalimi në përfaqësimin e frekuencës së vlerave të pikselit na lejon të hedhim një vështrim tjetër në imazh, ta përpunojmë atë dhe, çfarë është interesante për ne, ta kompresojmë atë. Për më tepër, duke ditur koeficientët e konvertimit, ne gjithmonë mund të kryejmë veprimin e kundërt - të kthejmë imazhin origjinal.

Një DCT e aplikuar drejtpërdrejt në një bllok (në rastin tonë 8x8 piksele) të një imazhi do të dukej kështu:

ku x, y - koordinatat hapësinore të një piksel (0..7) ,

f(x,y) - vlerat e pikselit të makrobllokut origjinal (le të themi ndriçimi)

u,v - koordinatat e pikselit në paraqitjen e frekuencës (0..7)

w(u) =1/SQRT(2) për u=0, përndryshe w(u)=1 (SQRT është rrënja katrore)

w(v) =1/SQRT(2) për v=0, përndryshe w(v)=1

Ose në formë matrice:

4. Kuantizimi i çdo blloku të koeficientëve DCT duke përdorur funksionet e peshës të optimizuara për perceptimin vizual të njeriut;

Transformimi kosinus diskret përgatit informacionin për kompresim dhe rrumbullakim me humbje. Për çdo element të matricës që transformohet, ekziston një element përkatës i matricës kuantizimi. Matrica që rezulton fitohet duke ndarë çdo element të matricës së transformuar me elementin përkatës të matricës së kuantizimit dhe më pas duke rrumbullakosur rezultatin në numrin e plotë më të afërt. Gjatë përpilimit të matricës së kuantizimit, elementët e saj të mëdhenj janë në këndin e poshtëm të majtë, kështu që kur ndahen me to, të dhënat në këtë cep pas transformimit të kosinusit diskret (vetëm ato që rrumbullakosin do të jenë më pak të dhimbshme) rrumbullakohen më përafërsisht. Përkatësisht informacion i humbur më pak e rëndësishme për ne se të tjerët.


5. Faza e Kompresimit sekondar

Faza e fundit e koduesit JPEG është kodimi i matricës që rezulton.

5.1 Permutacioni zigzag i 64 koeficientëve DCT

Pra, pasi kemi kryer një transformim DCT në një bllok vlerash 8x8, ne kemi bllok i ri 8x8. Pastaj, ky bllok 8x8 skanohet në një zigzag si ky:

(Numrat në bllokun 8x8 tregojnë rendin në të cilin shikojmë matricën 2-dimensionale 8x8)

0, 1, 5, 6,14,15,27,28,

2, 4, 7,13,16,26,29,42,

3, 8,12,17,25,30,41,43,

9,11,18,24,31,40,44,53,

10,19,23,32,39,45,52,54,

20,22,33,38,46,51,55,60,

21,34,37,47,50,56,59,61,

35,36,48,49,57,58,62,63

Siç mund ta shihni, së pari këndi i sipërm majtas është (0,0), pastaj vlera në (0,1), pastaj (1,0), pastaj (2,0), (1,1), (0, 2), (0.3), (1.2), (2.1), (3.0), etj.

Pasi të kemi bërë zigzag matricën 8x8, tani kemi një vektor me 64 koeficientë (0..63) Qëllimi i këtij vektori zigzag është që ne shikojmë koeficientët 8x8 DCT në rend rritës të frekuencave hapësinore. Pra, marrim një vektor të renditur sipas kritereve të frekuencës hapësinore: vlera e parë në vektor (indeksi 0) korrespondon me frekuencën më të ulët në imazh - shënohet me termin DC. Ndërsa indeksi në vektor rritet, marrim vlerat që korrespondojnë me frekuencat më të larta (vlera me indeksin 63 korrespondon me amplituda e frekuencës më të lartë në bllokun 8x8). Pjesa tjetër e koeficientëve DCT shënohet AC.

5.2 Enkodimi me gjatësinë e zerave (RLE)

Tani kemi një vektor me një sekuencë të gjatë zerosh. Ne mund ta përdorim këtë duke koduar zero të njëpasnjëshme. E RËNDËSISHME: Do ta shihni pse më vonë, por këtu ne kapërcejmë kodimin e koeficientit të parë të vektorit (koeficienti DC), i cili është i koduar ndryshe. Konsideroni vektorin origjinal 64 si një vektor 63 (ky është vektori 64 pa koeficientin e parë)

Le të themi se kemi 57,45,0,0,0,0,23,0,-30,-16,0,0,1,0,0,0,0,0,0, vetëm 0,... .0

Ja se si bëhet kompresimi RLC JPEG për këtë shembull:

(0.57); (0,45); (4.23); (1,-30); (0,-16); (2.1); EOB

Siç mund ta shihni, për çdo vlerë të ndryshme nga 0, ne kodojmë numrin e 0-ve të njëpasnjëshme PRIOR para vlerës, pastaj shtojmë vlerën. Një tjetër shënim: EOB është forma e shkurtër për Fundin e Bllokut dhe është një vlerë e veçantë e koduar (shënues). Nëse kemi arritur një pozicion në një vektor nga i cili kemi vetëm zero deri në fund të vektorit, ne do ta ndajmë atë pozicion me EOB dhe do ta përfundojmë ngjeshjen RLC të vektorit të kuantizuar.

[Vini re se nëse vektori i kuantizuar nuk është i përfunduar me zero (ka një element të fundit jo-0), ne nuk do të kemi një shënues EOB.]

(0,57); (0,45); (4,23); (1,-30); (0,-16); (2,1); (0,0)

Një tjetër gjë BAZË: Le të themi diku në vektorin e kuantizuar kemi:

57, tetëmbëdhjetë zero, 3, 0,0,0,0 2, tridhjetë e tre zero, 895, EOB

Kodimi JPG Huffman bën kufizimin që numri i zerave kryesore duhet të kodohet si një vlerë 4-bit - nuk mund të kalojë 15.

Pra, shembulli i mëparshëm duhet të kodohet si:

(0,57); (15,0) (2,3); (4,2); (15,0) (15,0) (1,895), (0,0)

(15,0) është një vlerë e veçantë e koduar që tregon atë që pason aty 16 zero të njëpasnjëshme.

5.3 Hapi i fundit - Kodimi i Huffman

Së pari një shënim i RËNDËSISHËM: Në vend që të ruajmë vlerën aktuale, standardi JPEG specifikon që ne të ruajmë madhësinë minimale në bit në të cilat mund ta mbajmë atë vlerë (kjo quhet kategoria e asaj vlere) dhe më pas një paraqitje të koduar me bit të asaj vlere. vlera si kjo:

7,..,-4,4,..,7 3 000,001,010,011,100,101,110,111

15,..,-8,8,..,15 4 0000,..,0111,1000,..,1111

31,..,-16,16,..,31 5 00000,..,01111,10000,..,11111

63,..,-32,32,..,63 6 .

127,..,-64,64,..,127 7 .

255,..,-128,128,..,255 8 .

511,..,-256,256,..,511 9 .

1023,..,-512,512,..,1023 10 .

2047,..,-1024,1024,..,2047 11 .

4095,..,-2048,2048,..,4095 12 .

8191,..,-4096,4096,..,8191 13 .

16383,..,-8192,8192,..,16383 14 .

32767,..,-16384,16384,..,32767 15 .

Më pas, për shembullin e mëparshëm:

(0,57); (0,45); (4,23); (1,-30); (0,-8); (2,1); (0,0)

le të kodojmë vetëm vlerën e duhur të këtyre çifteve, me përjashtim të çifteve që janë shënues të veçantë si (0,0) ose (nëse duhet të kemi) (15,0)

45, në mënyrë të ngjashme, do të kodohej si (6.101101)

30 -> (5,00001)

Dhe tani, ne do të shkruajmë përsëri vargun e çifteve:

(0,6), 111001; (0,6), 101101; (4,5), 10111; (1,5), 00001; (0,4), 0111; (2,1), 1; (0,0)

Çiftet e 2 vlerave të mbyllura në kllapa mund të përfaqësohen në një bajt, pasi në fakt secila nga 2 vlerat mund të përfaqësohet në një pjesë 4-bitësh (numri i zerave të parë është gjithmonë më pak se 15 dhe po kështu edhe kategoria [numrat e koduar në skedarin JPG - në zonën -32767..32767]). Në këtë bajt, biti i lartë përfaqëson numrin e zerot kryesore, dhe biti i ulët përfaqëson kategorinë e vlerës së re përveç 0.

Hapi i fundit i kodimit është që Huffman të kodojë atë bajt, dhe më pas të shkruajë në një skedar JPG, si një bitstream, kodin Huffman të atij bajt, i ndjekur nga përfaqësimi i bitit të atij numri.

Për shembull, për bajtin 6 (ekuivalent me (0.6)) kemi kodin Huffman = 111000;

21 = (1,5) - 11111110110

4 = (0,4) - 1011

33 = (2,1) - 11011

0 = EOB= (0.0) - 1010

Bitstream-i i fundit i shkruar në skedarin JPG në disk për shembullin e mëparshëm është 63 koeficientë (mos harroni se kemi hequr koeficientin e parë) -

111000 111001 111000 101101 1111111110011001 10111 11111110110 00001

1011 0111 11011 1 1010
Avantazhet dhe disavantazhet

Disavantazhet e formatit përfshijnë faktin se, me raporte të forta kompresimi, struktura e të dhënave të bllokut ndihet, imazhi "ndahet në katrorë" (secila me madhësi 8x8 piksele). Ky efekt është veçanërisht i dukshëm në zonat me frekuencë të ulët hapësinore (tranzicione të qetë të imazhit, si qielli i pastër). Në zonat me frekuencë të lartë hapësinore (për shembull, skajet e kundërta të imazhit), shfaqen "artefakte" karakteristike - një strukturë e parregullt pikselësh me ngjyrë dhe / ose shkëlqim të shtrembëruar. Përveç kësaj, detajet e vogla të ngjyrave zhduken nga imazhi. Gjithashtu nuk duhet harruar se formati i dhënë nuk mbështet transparencën.

Megjithatë, pavarësisht nga mangësitë e tij, JPEG u bë shumë i përhapur për shkak të raportit të lartë të kompresimit, në krahasim me alternativat ekzistuese në kohën e prezantimit të tij.

2. Algoritmi JPEG2000

Algoritmi JPEG-2000 u zhvillua nga i njëjti grup ekspertësh të fotografisë si JPEG. Formimi i JPEG si standard ndërkombëtar u përfundua në vitin 1992. Në vitin 1997, u bë e qartë se nevojitej një standard i ri, më fleksibël dhe i fuqishëm, i cili u finalizua në dimrin e vitit 2000.

Dallimet kryesore midis algoritmit në JPEG 2000 dhe algoritmit në JPEG janë si më poshtë:

1) Cilësi më e mirë e imazhit me një raport të fortë kompresimi. Ose, çfarë është e njëjta, një raport i madh kompresimi me të njëjtën cilësi për raporte të larta kompresimi. Në fakt, kjo do të thotë një reduktim i dukshëm në madhësinë e grafikëve "me cilësi në internet" të përdorura nga shumica e sajteve.

2) Mbështetni kodimin e zonës individuale me cilesia me e mire. Dihet se zona të caktuara të imazhit janë kritike për perceptimin njerëzor (për shembull, sytë në një fotografi), ndërsa cilësia e të tjerave mund të sakrifikohet (për shembull, sfondi). Me optimizimin "manual", rritja e raportit të kompresimit kryhet derisa cilësia të humbasë në një pjesë të rëndësishme të imazhit. Tani bëhet e mundur vendosja e cilësisë në zonat kritike, duke ngjeshur më fort pjesën tjetër të zonave, d.m.th. ne marrim një raport kompresimi përfundimtar edhe më të lartë me cilësi imazhi subjektivisht të barabartë.

3) Algoritmi kryesor i kompresimit është zëvendësuar me valëzues. Përveç rritjes së mësipërme të raportit të ngjeshjes, kjo eliminoi bllokimin e 8 pikselëve që ndodh kur rritet raporti i kompresimit. Për më tepër, zhvillimi i qetë i imazhit tani është në thelb standard (JPEG Progressive, i përdorur në mënyrë aktive në internet, u shfaq shumë më vonë se JPEG).

4) Për të rritur raportin e kompresimit, algoritmi përdor kompresimin aritmetik. Standardi JPEG fillimisht përfshinte edhe kompresimin aritmetik, por kjo më vonë u zëvendësua nga kompresimi më pak efikas i Huffman, sepse kompresimi aritmetik mbrohej nga patentat. Tani patenta kryesore ka skaduar dhe ekziston një mundësi për të përmirësuar algoritmin.

5) Mbështet kompresimin pa humbje. Përveç kompresimit të zakonshëm me humbje, JPEG-i i ri tani do të mbështesë gjithashtu kompresimin pa humbje. Kështu, bëhet e mundur përdorimi i JPEG për kompresimin e imazheve mjekësore, në printim, duke ruajtur tekstin për njohje nga sistemet OCR, etj.

6) Mbështet kompresimin e imazheve me një bit (2 ngjyra). Për ruajtjen e imazheve me një bit (vizatime me bojë, tekst të skanuar, etj.), formati GIF rekomandohej gjerësisht më parë, pasi kompresimi duke përdorur DCT është shumë joefikas për imazhet me tranzicion të mprehtë të ngjyrave. Në JPEG, kur kompresohej, një fotografi 1-bit reduktohej në një 8-bit, d.m.th. u rrit me 8 herë, pas së cilës u bë një përpjekje për të ngjeshur, shpesh më pak se 8 herë. Tani mund të rekomandojmë JPEG 2000 si një algoritëm universal.

7)Transparenca mbështetet në nivelin e formatit. Tani do të jetë e mundur të mbivendosni pa probleme sfondin kur krijoni faqe WWW jo ​​vetëm në GIF, por edhe në JPEG 2000. Përveç kësaj, mbështetet jo vetëm 1 bit transparencë (një piksel është transparent / i errët), por një kanal i veçantë, e cila do t'ju lejojë të vendosni një tranzicion të qetë nga një imazh i errët në sfond transparent.

Për më tepër, përfshirja e informacionit të së drejtës së autorit në imazh mbështetet në nivelin e formatit, mbështetja për rezistencën e gabimit të bitit gjatë transmetimit dhe transmetimit, mund të kërkohet për dekompresim ose përpunim. fondet e jashtme(plug-ins), ju mund të përfshini përshkrimin e tij, informacionin e kërkimit, etj. në imazh.

Fazat e kodimit

Procesi i kompresimit sipas skemës JPEG2000 përfshin një sërë hapash:

1. Konvertimi i imazhit në hapësirën optimale të ngjyrave.
Në këtë fazë të kodimit, duke përdorur raportet e duhura, modeli i ngjyrave RGB konvertohet në YUV:

Gjatë dekompresimit, zbatohet transformimi përkatës i anasjelltë:

2. Transformimi i valëzuar diskrete.

Diskret transformimi i valëzimit(DWT) gjithashtu mund të jetë dy llojesh - për rastin e kompresimit me humbje dhe për kompresimin pa humbje.

Ky transformim në rastin njëdimensional është prodhim skalar i koeficientëve përkatës dhe vargut të vlerave. Por që kur shumë koeficientë janë zero, atëherë transformimet e valëve të drejtpërdrejta dhe të anasjellta mund të shkruhen me formulat e mëposhtme (për të transformuar elementët ekstremë të linjës, përdoret shtrirja e saj me 2 pikselë në çdo drejtim, vlerat e të cilave janë simetrike me vlerat e elementeve të linjës në lidhje me pikselët e saj ekstremë):
y(2*n + 1) = x(2*n + 1) - (int)(x(2*n) + x(2*n + 2)) / 2

y(2*n) = x(2*n) + (int)(y(2*n - 1) + y(2*n + 1) + 2) / 4

dhe anasjelltas

x(2*n) = y(2*n) - (int)(y(2*n - 1) + y(2*n + 1) + 2) / 4

x(2*n + 1) = y(2*n + 1) + (int)(x(2*n) + x(2*n + 2)) / 2.

3. Kuantizimi i koeficientëve.

Ashtu si në algoritmin JPEG, kuantizimi përdoret kur kodoni një imazh në formatin JPEG2000. Transformimi i valëzuar diskrete, si analogu i tij, rendit koeficientët sipas frekuencës. Por, ndryshe nga JPEG, në formatin e ri matrica e kuantizimit është e njëjtë për të gjithë imazhin.


4. Faza e Kompresimit Sekondar

. Ashtu si me JPEG, në formatin e ri, hapi i fundit në algoritmin e kompresimit është kodimi pa humbje. Por, ndryshe nga formati i mëparshëm, JPEG2000 përdor një algoritëm aritmetik të kompresimit.

Implementimi i softuerit

Në këtë punim janë implementuar algoritmet JPEG dhe JPEG2000. Të dy algoritmet zbatojnë kodim të drejtpërdrejtë dhe të kundërt (nuk ka fazë të fundit të kompresimit dytësor). Llogaritja e JPEG merr një kohë mjaft të gjatë (rreth 30 sekonda) për shkak të llogaritjes "direkte" të DCT. Nëse keni nevojë për të rritur shpejtësinë e punës, fillimisht duhet të llogaritni matricën DCT (bëni ndryshime në klasën DCT).

Le t'i hedhim një sy programit:


  1. Pas nisjes, shfaqet një dritare ku

dhe mund ta ruani duke shtypur butonin (2) dhe duke futur emrin e dëshiruar në kutinë e dialogut.

  • Me një faktor cilësie mjaft të madh, imazhi do të ndryshojë në mënyrë dramatike. Nëse ky është një algoritëm JPEG, atëherë do të shqiptohen blloqe 8x8. (Në rastin e algoritmit JPEG2000, nuk do të ketë ndarje blloku)
  • Përpara:

    Pas:



    Artikujt kryesorë të lidhur