You are on page 1of 10

4 Алгоритми стиснення зображень

тиснення зображень — використання алгоритмів стиснення


даних до зображень, що зберігаються в цифровому виді. В результаті
стиснення зменшується розмір зображення, що зменшує час передачі
зображення по мережі і економить простір для зберігання. Стиснення
зображень розділяють на стиснення з втратами якості і стиснення без втрат.
Стиснення без втрат більш підходить для штучно побудованих зображень,
таких як графіки, іконки програм, або для спеціальних випадків, наприклад,
якщо зображення призначені для подальшої обробки алгоритмами
розпізнавання зображень.

Алгоритм RLE
Алгоритм RLE (Run Length Encoding) — один з найстаріших і
найпростіших алгоритмів архівації графіки. Зображення в ньому витягується
в ланцюжок байт по рядках растра. на зображення з невеликою кількістю
кольорів: ділову та наукову графіку. До позитивних сторін алгоритму можна
віднести тільки те, що він не вимагає додаткової пам'яті при архівації та
розархівації, а також швидко працює Саме стиснення в RLE відбувається за
рахунок того, що у вихідному зображенні зустрічаються ланцюжки
однакових байт. Алгоритм орієнтований.

Кодування довжин ділянок (або повторень) може бути достатньо


ефективним при стисненні двійкових даних, наприклад, чорно-білих
зображень що містять безліч прямих ліній і однорідних ділянок, схем і т.п.

Ідея стиснення даних на основі кодування довжин повторень полягає в


тому, що замість кодування власне дані піддають кодуванню числа, що
відповідають довжинам ділянок, на яких дані зберігають незмінне значення.

Припустимо, що потрібно закодувати двійкове зображення розміром 8


х 8 елементів.

Проскануємо це зображення по рядках (двом об’єктам на зображенні


відповідатимуть 0 і 1), в результаті отримаємо двійковий вектор даних,
наприклад:

довжиною 64 біта (швидкість початкового коду складає 1 біт на


елемент зображення).

Виділимо у векторі X ділянки, на яких дані зберігають незмінне


значення, і визначимо їх довжини. Результуюча послідовність довжин
ділянок - позитивних цілих чисел, що відповідають початковому вектору
даних , - матиме вид .

Тепер цю послідовність, в якій помітна певна повторюваність (одиниць


і четвірок значно більше, чим інших символів), можна закодувати яким-
небудь статистичним кодом, наприклад, кодом Хаффмена.

Для того, щоб вказати, що кодована послідовність починається з нуля,


додамо на початок кодового слова префіксний символ 0. В результаті
отримаємо кодове
слово довжиною в 34 біта, тобто
результуюча швидкість коду складе 34/64, або трохи більше 0,5 біт на
елемент зображення. При стисненні зображень більшого розміру і
повторюванні елементів, що містять множину, ефективність стиснення може
виявитися істотно вищою.

На слайді наведений інший приклад використання кодування довжин


повторень, коли в цифрових даних зустрічаються ділянки з великою
кількістю нульових значень. Кожного разу, коли в потоці даних зустрічається
“нуль”, він кодується двома числами. Перше - 0, такий, що є прапором
початку кодування довжини потоку нулів, і друге – кількість нулів в черговій
групі (Рис. 1.5). Якщо середнє число нулів в групі більше двох, матимемо
стиснення. З іншого боку, велике число окремих нулів може привести навіть
до збільшення розміру кодованого файлу.

Графічне зображення алгоритму кодування по довжині повторів нулів

Для більш ефективного стиску даних використовується також


побітовий RLE. Наприклад, якщо стискається чорно-біле зображення, підряд
зазвичай йде кілька 0 або 1, і виникає наступний нюанс: числа, що
позначають кількість повторень, також треба кодувати бітами і розмір коду
може бути більшим за розмір вихідного зображення.

Для подолання подібних ситуацій використовується наступний підхід:


кожне число повторень змінюється від 0 до 7 (тобто можна закодувати рівно
трьома бітами), тоді послідовності 11111111111 можна зіставити числа 704,
тобто. 7 одиниць, 0 нулів, 4 одиниці.
Наприклад, послідовність, що складається з 21 одиниці, 21 нуля, 3
одиниць і 7 нулів закодується так: 111 000 111 000 111 111 000 111 000 111
011 111, тобто. з вихідної послідовності, яка має довжину 51 біт, отримали
послідовність завдовжки 36 біт.

Ідея цього використовується при передачі факсів.

ловникові алгоритми

Головна ідея, що лежить в основі алгоритмів даного типу, полягає в


тому, що замість кодування тільки по одному елементу послідовності
входить проводиться кодування ланцюжка елементів. При цьому
використовується словник ланцюжків (створений за вхідною послідовністю)
для кодування нових.

Алгоритм LZ77

LZ77 - алгоритм стиснення без втрат, опублікований у статтях


ізраїльських математиків Авраама Лемпеля (англ.) та Яакова Зіва в 1977 та
1978 роках.

Дані алгоритм заснований на принципі ковзного вікна та механізмі


кодування збігів.

В основі алгоритму лежить стиск із використанням рядків словника.


Однак замість використання статичного, заздалегідь згенерованого словника,
запропонований ними алгоритм генерує словник "на льоту", на основі даних,
які програма стиснення вже зустріла у вхідному файлі. А замість
використання номерів сторінок та слів вони запропонували виводити
значення відстані та довжини. Робота алгоритму виконується наступним
чином: під час зчитування вхідного файлу робиться спроба зіставити набір
символів у поточній позиції з чимось, що вже зустрічається у вхідному файлі.
При виявленні збігу обчислюється відстань рядка, що збігається від поточної
позиції і кількість збігаються байтів (довжина). У разі виявлення кількох
збігів вибирається найдовший з них.

Нехай є така безглузда фраза:

the brown fox jumped over the brown fox y jumping frog

Алгоритм обробляє цей текст зліва направо.

Під час обробки тексту алгоритм шукає послідовності, що


повторюються. Коли зустрічається послідовність, що повторюється,
алгоритм шукає кінець такої послідовності, тобто кожен раз алгоритм
відшукує якомога більше символів. Першою такою послідовністю є the brown
fox. Повторююча послідовність замінюється покажчиком перший екземпляр
послідовності і довжиною цієї послідовності. У разі послідовність the brown
fox зустрічається на 26 позицій раніше і має довжину 13 символів. Для
даного прикладу розглянемо два варіанти кодування: 8-бітовий покажчик та
4-бітова довжина або 12-бітовий покажчик та 6-бітова довжина. При цьому 2-
бітовий заголовок вказує, який варіант обраний: 00 означає перший варіант, а
01 - другий варіант. Таким чином, другий екземпляр послідовності the brown
fox кодується як <00b><26d><13d> або 00011010 1101.

Частини стисненого повідомлення, що залишилися, є буквою у,


послідовність <00b><27d><5d>, що замінює послідовність, що складається з
пробілу, за яким слідує рядок jump, і послідовність символів «ing frog».

Даний алгоритм є родоначальником цілого сімейства алгоритмів, і сам


по собі у первісному вигляді практично не використовується. До його
переваг можна віднести пристойний ступінь стиснення на досить великих
послідовностях, швидке розпакування, а також відсутність патенту5 на
алгоритм. До недоліків відносять повільну швидкість стиснення, а також
меншу, ніж у альтернативних алгоритмів, ступінь стиснення (модифікації
алгоритму борються із цим недоліком). Поєднання алгоритмів Хаффмена
(Huffman) ("Алгоритми стиснення зображень без втрат") і LZ77 називають
методом DEFLATE6. Метод DEFLATE використовується у графічному
форматі PNG, а також у універсальному форматі стиснення даних ZIP.

LZ78

На відміну від LZ77, що працює з вже отриманими даними, LZ78


орієнтується на дані, які тільки будуть отримані (LZ78 не використовує
вікно, що ковзає, він зберігає словник з вже переглянутих фраз). Алгоритм
зчитує символи повідомлення до тих пір, поки підстрока, що накопичується,
входить цілком в одну з фраз словника. Як тільки цей рядок перестане
відповідати хоча б одній фразі словника, алгоритм генерує код, що
складається з індексу рядка в словнику, який до останнього введеного
символу містив вхідний рядок, і символ, що порушив збіг. Потім до словника
додається введений підрядок. Якщо словник вже заповнений, то з нього
попередньо видаляють найменшу фразу, що використовується в порівняннях.

Алгоритми статистичного кодування


Алгоритми статистичного кодування ставлять у відповідність кожному
елементу послідовності код так, щоб його довжина відповідала ймовірності
появи елемента. Таким чином, стиск відбувається за рахунок заміни
елементів вихідної послідовності, що мають однакові довжини (кожний
елемент займає однакову кількість біт), на елементи різної довжини,
пропорційної негативному логарифму від ймовірності, тобто. елементи, що
зустрічаються частіше, ніж інші, матимуть код меншої довжини.

Алгоритм Хаффмена

Алгоритм Хаффмена8 використовує особливий вид представлення


елементів – префіксний код. Префіксний код - це код змінної довжини, що
має особливу властивість - властивість префікса: менш короткі коди не
збігаються з префіксом (початковою частиною) довших. Такий код дозволяє
здійснювати однозначне взаємно кодування. Відповідно, потрібно
побудувати спосіб стиснення, який використовує префіксний код і при цьому
забезпечує максимально можливий ступінь стиснення.

Стискаючи файл за алгоритмом Хаффмана перше, що ми повинні


зробити - це необхідно прочитати файл повністю і підрахувати скільки разів
зустрічається кожен символ з розширеного набору ASCII. Якщо ми
враховуватимемо всі 256 символів, то для нас не буде різниці в стисненні
текстового та EXE файлу.

Після підрахунку частоти входження кожного символу, необхідно


переглянути таблицю кодів ASCII і сформувати уявне компонування між
кодами за спаданням. Тобто не змінюючи місцезнаходження кожного
символу з таблиці у пам'яті відсортувати таблицю посилань на них за
спаданням. Кожне посилання з останньої таблиці назвемо "вузлом". Надалі (
в дереві ) ми пізніше розміщуватимемо покажчики які будуть вказувати на
цей "вузол". Для ясності давайте розглянемо приклад:

Ми маємо файл довжиною 100 байт і має 6 різних символів у собі. Ми


підрахували входження кожного із символів у файл і отримали наступне:

|-----------------|-----|-----|-----|-----|-----|-----|

| cимвол | A | B | C | D | E | F |

|-----------------|-----|-----|-----|-----|-----|-----|
| число вхождений | 10 | 20 | 30 | 5 | 25 | 10 |

|-----------------|-----|-----|-----|-----|-----|-----|

Тепер ми беремо ці числа і називатимемо їх частотою входження для


кожного символу. Розмістимо таблицю як нижче.
|-----------------|-----|-----|-----|-----|-----|-----|

| cимвол | C | E | B | F | A | D |

|-----------------|-----|-----|-----|-----|-----|-----|

| число вхождений | 30 | 25 | 20 | 10 | 10 | 5 |

|-----------------|-----|-----|-----|-----|-----|-----|

Ми візьмемо із останньої таблиці символи з найменшою частотою. У


нашому випадку це D (5) і будь-який символ F або A (10), можна взяти будь-
який з них наприклад A.

Сформуємо з "вузлів" D і A новий "вузол", частота входження для


якого дорівнюватиме сумі частот D і A :

Частота 30 10 5 10 20 25

Символа C A D F B E

| |

|--|--|

||-|

|15| = 5 + 10

|--|

Номер у рамці – сума частот символів D та A. Тепер ми знову шукаємо


два символи з найнижчими частотами входження. Виключаючи з перегляду
D і A і розглядаючи замість них новий "вузол" із сумарною частотою
входження. Найнижча частота тепер у F та нового "вузла". Знову зробимо
операцію злиття вузлів:

Частота 30 10 5 10 20 25

Символа C A D F B E

| | |

| | |

| |--|| |

|-|15|| |

||-| |

| |

| |--| |

|----|25|-| = 10 + 15

|--|

Розглядаємо таблицю знову для наступних двох символів (B та E). Ми


продовжуємо у цей режим поки що все "дерево" не сформовано, тобто. доки
все не зведеться до одного вузла.

Частота 30 10 5 10 20 25

Символа C A D F B E

| | | | | |

| | | | | |

| | |--|| | | |

| |-|15|| | | |
| ||-| | | |

| | | | |

| | |--| | | |--| |

| |----|25|-| |-|45|-|

| ||-| ||-|

| |--| | |

|----|55|------| |

|-|| |

| |------------| |

|---| Root (100) |----|

|------------|

Тепер, коли наше дерево створене, ми можемо кодувати файл. Ми


повинні всенда починати з кореня (Root). Кодуючи перший символ (аркуш
дерева С) Ми простежуємо вгору по дереву всі повороти гілок і якщо ми
робимо лівий поворот, то запам'ятовуємо 0-й біт і аналогічно 1-й біт для
правого повороту. Так для C, ми будемо йти вліво до 55 (і запам'ятаємо 0),
потім знову вліво (0) до символу. Код Хаффмана для нашого символу C - 00.
Для наступного символу ( А ) у нас виходить - ліво, право, ліво, ліво, що
виливається в послідовність 0100. Виконавши вище сказане всім символів
отримаємо C = 00 ( 2 бита )

A = 0100 ( 4 бита )

D = 0101 ( 4 бита )

F = 011 ( 3 бита )

B = 10 ( 2 бита )

E = 11 ( 2 бита )

Необхідність стиснення із втратами

Як зазначено в першому параграфі попередньої лекції, обсяг


інформації, яка потрібна для зберігання зображень, зазвичай великий. При
цьому з кожним днем роздільна здатність пристроїв введення зображень
зростає. Деякий час тому стало очевидним, що класичні алгоритми не
забезпечують достатнього стиску. Як алгоритми загального призначення,
вони не враховували того, що стислива інформація є зображення. Відповідно,
були розроблені алгоритми, що забезпечують стиск із втратами інформації,
які дозволили суттєво підняти ступінь компресії.

Стиснення з втратами ґрунтується на особливостях сприйняття


людиною зображення: найбільшої чутливості у певному діапазоні хвиль
кольору, здатності сприймати зображення як єдине ціле, не помічаючи
дрібних спотворень. Також використовується той факт, що зображення –
двомірний об'єкт. Головний клас зображень, на який орієнтовані алгоритми
стиснення з втратами, - фотографії, зображення з плавними переходами
кольорів.

Алгоритм стиснення зображень JPEG

JPEG (вимовляється «джейпег», англ. Joint Photographic Experts Group,


за назвою організації-розробника) - один з популярних растрових графічних
форматів, що використовується для зберігання фотографій та подібних до
них зображень. Файли, що містять дані JPEG, зазвичай мають розширення
(суфікси) .jpg (найпопулярніше), .jfif, .jpe або .jpeg. MIME-тип - image/jpeg.

Алгоритм JPEG дозволяє стискати зображення як із втратами, так і без


втрат (режим стиснення lossless JPEG). Підтримуються зображення з
лінійним розміром не більше 65 535 × 65 535 пікселів.

Алгоритм JPEG найбільш ефективний для стиснення фотографій та


картин, що містять реалістичні сцени з плавними переходами яскравості та
кольору. Найбільше поширення JPEG отримав у цифровій фотографії та для
зберігання та передачі зображень з використанням Інтернету.

Основна ідея методу - розбиття зображення на невеликі блоки з подальшим


стисканням їх коду, яке візуально відображається згладжуванням дрібних
деталей всередині блоків. :

Приклад згладжування дрібних деталей в блоку зображення JPEG

- згладжування досягається за рахунок використання спектрального


перетворення і придушення високочастотних складових. На цьому етапі
виникають втрати якості зображення, які, тим не менш суб'єктивно
сприймаються як прийнятні (приклад - на рис.6.8);
- метод JPEG поєднує застосування спектрального перетворення з
використанням стискання без втрат (кодування Хаффмена), а також
інженерних рішень з попередньої по підготовки до стискання (наприклад,
поділу яскравісної та колірних складових з додатковим огрубленням
останніх);

- зазвичай зображення в JPEG стискаються в 10-15 разів без істотної втрати


якості. При більш сильному стисканні проявляється мозаїчність зображення,
а також так званий «ефект Гібсона» - більш явне виділення меж різких
колірних переходів. Час стискання і відновлення зображення близькі між
собою.

Алгоритм JPEG включає три послідовні етапи, зміст яких істотно різниться.

You might also like