Skip to content
ЦОС · Тема 8 · Компресия

Трансформации и JPEG

Как JPEG прави папагала 10 пъти по-малък, без окото да забележи? Снимката се реже на квадратчета 8×8 и всяко се описва като сума от шаблони – а повечето шаблони почти не участват. Същото правим и с думата „Здравей“.

≈ 5 мин четене∿ 6 живи уредаСамопроверка: 4 въпроса

Идеята: два съседни пиксела ​

Съседните пиксели на снимката почти винаги си приличат: 100 и 101, 37 и 39. Ако ги нанесем като точки (x₁, x₂), облакът лежи по диагонала. Да завъртим осите на 45°: новите числа са „сумата“ y₁ и „разликата“ y₂. Почти цялата енергия отива в y₁, а y₂ е малко число около нулата – него можем да запишем грубо или изобщо да не го пазим.

Завъртане на два пиксела
корелация на съседите ρ = 0,97
ъгъл на завъртане θ = 45°
Преди: точките лежат по диагонала
0501001502002500100200x₁ – яркостx₂
двойка (x₁, x₂)
След завъртане: 98,4 % от енергията е в y₁
−200−1000100200300−200−1000100200y₁ („сума“)y₂ („разлика“)
двойка (y₁, y₂)
Фигура 1.

Ляво – двойки съседни пиксели; дясно – същите след завъртане на θ. Най-много енергия в y₁ има точно при 45°. Намали корелацията ρ към 0 – облакът става кръг и никое завъртане не помага: печелим само защото съседите си приличат.

Пример: 100 и 101 → y₁ ≈ 142,1, y₂ ≈ 0,7; енергията 20 201 е същата. Без y₂ възстановяваме 100,5 и 100,5 – грешка 0,5, а пазим половината числа.

Ортогонални трансформации и базис ​

Завъртането се записва с матрица: Y = T·X. Ако матрицата е ортогонална, обратната е просто транспонираната – връщането е „безплатно“. Редовете ѝ са базисните вектори – шаблоните. Всеки коефициент yₖ казва „колко от k-тия шаблон има в сигнала“.

ТрансформацияШаблонитеЗащо се ползва
DCT (косинусна)косинусипочти оптимална; JPEG, MPEG, MP3
DFT (Фурие)комплексни синусоидиспектър; комплексна
WHT (Уолш–Адамар)стъпала ±1само събиране и изваждане – най-бърза
KLT (Карунен–Лоев)собствени вектори на даннитеоптимална, но зависи от данните

По качество: KLT > DCT > DFT > WHT.

Шаблоните при N = 8
0246−0,500,5n – отчетстойност
k = 0
0246−0,500,5n – отчетстойност
k = 1
0246−0,500,5n – отчетстойност
k = 2
0246−0,500,5n – отчетстойност
k = 3
0246−0,500,5n – отчетстойност
k = 4
0246−0,500,5n – отчетстойност
k = 5
0246−0,500,5n – отчетстойност
k = 6
0246−0,500,5n – отчетстойност
k = 7
Фигура 2.

k = 0 е постоянен (средното), всеки следващ се люшка по-бързо. Смени на WHT: шаблоните са стъпала ±1, подредени по брой смени на знака.

Кодиране чрез трансформация ​

Трансформацията сама не компресира: N числа стават N числа. Компресира следващата стъпка – малките коефициенти се изхвърлят или записват с малко битове. Схемата: трансформация → квантуване → кодиране → … → обратна трансформация.

Думата „Здравей“ на блокове по 256 отчета: от всеки блок пазим само 24 най-големи коефициента с DCT – 10,7 пъти по-малко числа, SNR = 12,6 dB.

Думата с малко коефициенти
Входът: звукът, както е записан
020040060080010001200−101t – време, msx
входът x(n)
Изходът: звукът от малко коефициенти
020040060080010001200−101t – време, msy
изходът y(n)
Спектрограма: остават само най-силните честоти
Фигура 3.

С DCT и 24 от 256 думата се разбира ясно (≈ 10 пъти по-малко числа). Под ~8 звучи „металически“ – остават само няколко честоти във всеки блок. WHT при същия брой звучи по-зле: стъпалата не приличат на гласа. Така, но с по-хитра трансформация (MDCT) и модел на слуха, работи MP3.

Отблизо: 64 отчета, M коефициента
пазим M = 8 от 64
шум = 0,05
Пазим 8 от 64 → компресия 8:1, PSNR = 17,1 dB
0204060−101n – отчетx(n)
оригинал възстановен
|Y(k)|: запазените носят 91,2 % от енергията
02040600123k – номер на коефициента|Y(k)|
изхвърлени запазени
Фигура 4.

Горе – сигналът и възстановеният от M коефициента; долу – коефициентите (червените са запазените). Правоъгълен сигнал: на WHT стига един коефициент, на DCT – много. Шумът се разпилява по всички коефициенти и не се компресира.

2D трансформация и JPEG ​

Снимката е двумерна: блок 8×8 се трансформира първо по редове, после по колони (разделимост). Резултатът са 64 коефициента F(u, v): горе вляво е DC – средната яркост, надясно и надолу – все по-фини шарки. При снимки почти цялата енергия е горе вляво.

Тук папагалът е нарязан на 24 × 24 блока и от всеки блок пазим 6 коефициента с DCT: 10,7 пъти по-малко числа, PSNR = … dB.

JPEG на папагала
оригиналът
6 от 64 коефициента на блок
грешката ×4
Фигура 5.

С 6 от 64 (≈ 10 пъти) разликата почти не се вижда. С 1 остава само DC – мозайка от квадратчета 8×8: така изглежда силно компресиран JPEG. Зоната губи ръбовете (клюна, перата), които праговото кодиране намира. WHT дава стъпаловидни блокове.

Един блок отблизо
зона K = 4
Оригинал 8×8
(0, 0): 67(0, 1): 74,9(0, 2): 84,5(0, 3): 91,4(0, 4): 91,4(0, 5): 84,5(0, 6): 74,9(0, 7): 67(1, 0): 74,9(1, 1): 91,4(1, 2): 112(1, 3): 127(1, 4): 127(1, 5): 112(1, 6): 91,4(1, 7): 74,9(2, 0): 84,5(2, 1): 112(2, 2): 145(2, 3): 170(2, 4): 170(2, 5): 145(2, 6): 112(2, 7): 84,5(3, 0): 91,4(3, 1): 127(3, 2): 170(3, 3): 201(3, 4): 201(3, 5): 170(3, 6): 127(3, 7): 91,4(4, 0): 91,4(4, 1): 127(4, 2): 170(4, 3): 201(4, 4): 201(4, 5): 170(4, 6): 127(4, 7): 91,4(5, 0): 84,5(5, 1): 112(5, 2): 145(5, 3): 170(5, 4): 170(5, 5): 145(5, 6): 112(5, 7): 84,5(6, 0): 74,9(6, 1): 91,4(6, 2): 112(6, 3): 127(6, 4): 127(6, 5): 112(6, 6): 91,4(6, 7): 74,9(7, 0): 67(7, 1): 74,9(7, 2): 84,5(7, 3): 91,4(7, 4): 91,4(7, 5): 84,5(7, 6): 74,9(7, 7): 67
|F(u,v)| – пазим 10 от 64
(0, 0): 911(0, 1): 0(0, 2): −206(0, 3): 0(0, 4): −4,89(0, 5): 0(0, 6): −3,5(0, 7): 0(1, 0): 0(1, 1): 0(1, 2): 0(1, 3): 0(1, 4): 0(1, 5): 0(1, 6): 0(1, 7): 0(2, 0): −206(2, 1): 0(2, 2): 98,2(2, 3): 0(2, 4): 2,33(2, 5): 0(2, 6): 1,67(2, 7): 0(3, 0): 0(3, 1): 0(3, 2): 0(3, 3): 0(3, 4): 0(3, 5): 0(3, 6): 0(3, 7): 0(4, 0): −4,89(4, 1): 0(4, 2): 2,33(4, 3): 0(4, 4): 0,0554(4, 5): 0(4, 6): 0,0396(4, 7): 0(5, 0): 0(5, 1): 0(5, 2): 0(5, 3): 0(5, 4): 0(5, 5): 0(5, 6): 0(5, 7): 0(6, 0): −3,5(6, 1): 0(6, 2): 1,67(6, 3): 0(6, 4): 0,0396(6, 5): 0(6, 6): 0,0284(6, 7): 0(7, 0): 0(7, 1): 0(7, 2): 0(7, 3): 0(7, 4): 0(7, 5): 0(7, 6): 0(7, 7): 0
Възстановен: PSNR 26,3 dB
(0, 0): 46,7(0, 1): 66,4(0, 2): 94,2(0, 3): 114(0, 4): 114(0, 5): 94,2(0, 6): 66,4(0, 7): 46,7(1, 0): 66,4(1, 1): 86,1(1, 2): 114(1, 3): 134(1, 4): 134(1, 5): 114(1, 6): 86,1(1, 7): 66,4(2, 0): 94,2(2, 1): 114(2, 2): 142(2, 3): 161(2, 4): 161(2, 5): 142(2, 6): 114(2, 7): 94,2(3, 0): 114(3, 1): 134(3, 2): 161(3, 3): 181(3, 4): 181(3, 5): 161(3, 6): 134(3, 7): 114(4, 0): 114(4, 1): 134(4, 2): 161(4, 3): 181(4, 4): 181(4, 5): 161(4, 6): 134(4, 7): 114(5, 0): 94,2(5, 1): 114(5, 2): 142(5, 3): 161(5, 4): 161(5, 5): 142(5, 6): 114(5, 7): 94,2(6, 0): 66,4(6, 1): 86,1(6, 2): 114(6, 3): 134(6, 4): 134(6, 5): 114(6, 6): 86,1(6, 7): 66,4(7, 0): 46,7(7, 1): 66,4(7, 2): 94,2(7, 3): 114(7, 4): 114(7, 5): 94,2(7, 6): 66,4(7, 7): 46,7
Фигура 6.

Ляво – блок 8×8; среда – |F(u, v)| (по-синьо = по-голям); дясно – възстановеният. „Вертикален ръб“ има енергия само в първия ред – зоната го реже, праговото кодиране го пази.

Праговото кодиране в JPEG: (1) коефициентите под праг стават 0; (2) останалите се делят на таблица Γ(u, v) – голям делител за високите честоти; (3) закръгляне; (4) много нули → почти без битове. Пример: [620, 41, −12, 6, 3] с праг 5 и Γ = [16, 11, 10, 16, 24] → [38, 3, −1, 0, 0].

Бързи алгоритми ​

Директно умножение по матрица струва N² операции. Бързите алгоритми разлагат матрицата на log₂N прости стъпки от „пеперуди“ (a + b, a − b) – N·log₂N операции. При N = 1024 това е ≈ 100 пъти по-бързо. Бързата DCT за N = 8 (Arai–Agui–Nakajima) иска само 5 умножения вместо 64.

Самопроверка ​

1. Компресира ли сама по себе си DCT?

Не – N числа стават N числа. Компресира изхвърлянето и грубото квантуване на малките коефициенти.

2. Пиксели 100 и 101 – колко са y₁ и y₂ при завъртане на 45°?

y₁ ≈ 142,1, y₂ ≈ 0,7; енергията 20 201 се запазва.

3. Защо JPEG при силна компресия показва квадратчета?

Остава почти само DC на всеки блок 8×8 – блокът става равномерен, а съседните блокове имат различни средни.

4. WHT на [5, 5, 4, 4]?

С H(4) (без нормиране): [18, 0, 2, 0] – „средно“ и „една смяна по средата“.