Алгоритм стиснення з втратами. Фрактальний алгоритм

  • Вид работы:
    Курсовая работа (т)
  • Предмет:
    Информационное обеспечение, программирование
  • Язык:
    Украинский
    ,
    Формат файла:
    MS Word
    508,78 Кб
  • Опубликовано:
    2017-07-10
Вы можете узнать стоимость помощи в написании студенческой работы.
Помощь в написании работы, которую точно примут!

Алгоритм стиснення з втратами. Фрактальний алгоритм

Київський національний університет будівництва і архітектури

Кафедра кібернетичної безпеки та комп’ютерної інженерії









Курсова робота

з дисципліни «Теорія інформації та кодування»

на тему: Алгоритм стиснення з втратами. Фрактальний алгоритм












Київ-2017

ВСТУП


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

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

Метою цієї роботи є побудова методу фрактального стиснення для зображень. В роботі розглядаються основні принципи методу, його обґрунтування, алгоритм його реалізації.


РОЗДІЛ 1. ЗАГАЛЬНІ ВІДОМОСТІ


.1 Стиснення з втратами

Говорячи про коди стиснення, розрізняють поняття «стиснення без втрат» і «стиснення з втратами». Очевидно, що коли ми маємо справу з інформацією типу «номер телефону», то стиснення такого запису за рахунок втрати частини символів не веде ні до чого хорошого. Проте можна уявити цілий ряд ситуацій, коли втрата частини інформації не призводить до втрати корисності залишилася. Стиснення з втратами застосовується в основному для графіки (JPEG), звуку (MP3), відео (MPEG), тобто там, де в силу величезних розмірів файлів ступінь стиснення дуже важлива, і можна пожертвувати деталями, неістотними для сприйняття цієї інформації людиною. Особливі можливості для стиснення інформації є при компресії відео. У ряді випадків більша частина зображення передається з кадру в кадр без змін, що дозволяє будувати алгоритми стиснення на основі вибіркового відстеження тільки частини «картинки». В окремому випадку зображення людини, що говорить, що не змінює свого положення, може оновлюватися тільки в області особи або навіть тільки рота - тобто в тій частині, де відбуваються найбільш швидкі зміни від кадру до кадру.

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

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

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

Тепер перейдемо до розгляду про стиснення інформації без втрат і розглянемо фрактальний алгоритм[7].

1.2 Алгоритм фрактального стиснення


Фрактальное стиснення зображень - алгоритм стиснення зображень c втратами, заснований на застосуванні систем ітеріруемих функцій (як правило є аффіннимі перетвореннями) до зображень. Даний алгоритм відомий тим, що в деяких випадках дозволяє отримати дуже високі коефіцієнти стиснення при прийнятному візуальному якості для реальних фотографій природних об'єктів. Через складну ситуацію з патентуванням широкого поширення алгоритм не отримав[2].

Фрактальна архівація заснована на тому, що ми представляємо зображення в більш компактній формі - за допомогою коефіцієнтів системи ітеріруемих функцій (Iterated Function System - далі по тексту як IFS). Перш, ніж розглядати сам процес архівації, розберемо, як IFS будує зображення, тобто процес декомпресії.

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

Найбільш наочно цей процес продемонстрував Барнслі в своїй книзі 'Fractal Image Compression'. Там введено поняття фотокопіювальних Машини, що складається з екрану, на якому зображена вихідна картинка, і системи лінз, що проектують зображення на інший екран:

·        Лінзи можуть проектувати частина зображення довільної форми в будь-яке інше місце нового зображення.

·        Області, в які проектується зображення, не перетинаються.

·        Лінза може змінювати яскравість і зменшувати контрастність.

·        Лінза може дзеркально відображати і повертати свій фрагмент зображення.

·        Лінза повинна масштабувати (зменшувати) свій фрагмент зображення.

Рисунок 1.1 - Фотокопіювальна машина

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

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

Найбільш відомі два зображення, отриманих за допомогою IFS: 'трикутник Серпінського'(рисунок 1.2) і 'папороть Барнслі'(рисунок 1.3). 'Трикутник Серпінського' задається трьома, а 'папороть Барнслі' чотирма аффіннимі перетвореннями (або, в нашій термінології, 'лінзами'). Кожне перетворення кодується буквально ліченими байтами, в той час як зображення, побудоване з їх допомогою, може займати і кілька мегабайт.

Рисунок 1.2 - Трикутник Серпінського

Рисунок 1.3 - Папороть Барнслі

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

У гіршому випадку, коли не буде застосовуватися оптимізує алгоритм, буде потрібно перебір і порівняння всіх можливих фрагментів зображення різного розміру. Навіть для невеликих зображень при обліку дискретності ми отримаємо астрономічне число перебираються варіантів. Причому, навіть різке звуження класів перетворень, наприклад, з допомогою масштабування тільки в певну кількість разів, не дає помітного виграшу в часі. Крім того, при цьому втрачається якість зображення. Переважна більшість досліджень в області фрактальної компресії зараз спрямовані на зменшення часу архівації, необхідної для отримання якісного зображення[6].

.3 Типова схема фрактального стиснення

З урахуванням вищесказаного, схема компресії виглядає так: зображення R розбивають на рангові області R. Далі для кожної області R знаходять область D і перетворення w такі, що виконуються наступні умови:

)        D за розмірами більше R.

)        w (R) має ту ж форму, розміри і положення, що і R.

)        Коефіцієнт перетворення повинен бути менше одиниці.

)        Значення має бути якомога менше.

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

Таким чином, для компресії зображення W потрібно:

)        Розбити зображення на рангові області R (непересічні області, що покривають все зображення).

)        Для кожної рангової області R знайти область D, і відображення w, з зазначеними вище властивостями.

)        Запам'ятати коефіцієнти афінних перетворень W, положення доменних областей D, а також розбиття зображення на домени.

Відповідно, для декомпресії зображення потрібно буде:

)        Створити початкове зображення R.

)        Багаторазово застосувати до нього відображення W (об'єднання w).

)        Так як відображення W стискуюче, то в результаті, після достатньої кількості ітерацій, зображення прийде до аттрактору і перестане змінюватися. Аттрактор і є нашим вихідним зображенням. Декомпресія завершена[4].

.4 Побудова алгоритму , афінне перетворення

Як вже стало очевидним з викладеного вище, основним завданням при компресії фрактальним алгоритмом є знаходження відповідних афінних перетворень.

Афінне перетворення (від лат. Affinis - дотичний, близький, суміжний) - відображення площини або простору в себе, при якому паралельні прямі переходять в паралельні прямі, що перетинаються в пересічні, перехресні в перехресні [5].

Афінне перетворення f:RR є перетворення виду

f(x)=M*x+v,

де M - оборотна матриця та vR.

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

У моєму варіанті алгоритму, викладеному далі, зроблені наступні обмеження на області:

1)      Всі області є квадратами зі сторонами, паралельними сторонам зображення. Це обмеження досить жорстке. Фактично ми збираємося апроксимувати все різноманіття геометричних фігур лише квадратами.

2)      При перекладі доменної області в рангову зменшення розмірів виробляється рівно в два рази. Це істотно спрощує як компресор, так і декомпресор, тому що задача масштабування невеликих областей є нетривіальною.

3)      Всі доменні блоки - квадрати і мають фіксований розмір. Зображення рівномірної сіткою розбивається на набір доменних блоків.

4)      Доменні області беруться 'через точку' і по Х, і по Y, що відразу зменшує перебір в 4 рази.

5)      При перекладі доменної області в рангову поворот куба можливий тільки на 00, 900, 1800 або 2700. Також допускається дзеркальне відображення. Загальна кількість можливих перетворень (вважаючи пусте) - 8.

6)      Масштабування (стиснення) по вертикалі (яскравості) здійснюється в фіксоване число раз - в 0,75

Рисунок 1.4 - Розбиття квадрату на доменні блоки

Ці обмеження дозволяють:

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

)        Дуже компактно представити дані для запису в файл. Нам потрібно на кожне афінне перетворення в IFS:

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

·        три біта для того, щоб задати перетворення симетрії при перекладі доменного блоку в рангові.

·        7-9 біт для того, щоб задати зсув по яскравості при перекладі.

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


.5 Аналіз роботи

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

)        Оскільки всі області є квадратами, неможливо скористатися подобою об'єктів, по формі далеких від квадратів (які зустрічаються в реальних зображеннях досить часто.)

)        Аналогічно ми не зможемо скористатися подобою об'єктів в зображенні, коефіцієнт подібності між якими сильно відрізняється від 2.

)        Алгоритм не зможе скористатися подобою об'єктів в зображенні, кут між якими не кратний 900.

Така плата за швидкість компресії і за простоту упаковки коефіцієнтів в файл.

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

А зараз я хотів би порівняти фрактальний алгоритм з найбільш розповсюдженим алгоритмом архівації графіки - JPEG.

По-перше, зауважимо, що і той, і інший алгоритм оперують 8-бітними (в градаціях сірого) і 24-бітними кольоровими зображеннями. Обидва є алгоритмами стиснення з втратами і забезпечують близькі коефіцієнти архівації. І у фрактального алгоритму, і у JPEG існує можливість збільшити ступінь стиснення за рахунок збільшення втрат. Крім того, обидва алгоритму дуже добре распараллелівать.

Відмінності починаються, якщо ми розглянемо час, необхідне алгоритмам для архівації / розархівації. Так, фрактальний алгоритм стискає в сотні і навіть в тисячі разів довше, ніж JPEG. Розпакування зображення, навпаки, відбудеться в 5-10 разів швидше. Тому, якщо зображення буде стисло тільки один раз, а передано по мережі і Розпаковано безліч разів, то вигідніше використовувати фрактальний алгоритм.

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

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

 

РОЗДІЛ 2. СПЕЦІАЛЬНА ЧАСТИНА


2.1 Постановка задачі


Користувач запучкає програму , у головному вікні потрібно вибрате зображення , яке буде використано для перетворення. Після вибору зображення , користуач налаштовує необхідні параметри для стиснення. Після вибору параметрів , натискаємо кнопку запустить , і відбувається процедура стиснення , це може зайняти деякий час. Після завершення процедури , можна переглянути стиснене зображення , зберегти його або видалити.

2.2 Вхідні та вихідні дані


Вхідними даними моєї програми є зображення з розмірами не більші ніж 512х512.

Вихідними даними є зображення , стиснене фрактальним алгоритмом.

Результат роботи виводить стинену картинку та розмір в бітах.

2.3 Опис алгоритму


Дана програма використовує алгоритм фрактального стиснення. Зараз я опишу свою програму та для прикладу зроблю перетворення з декількома картинками.

Для початку зробимо запуск програми і побачимо головне вікно (Рисунок 2.1).

Нижче показано скільки часу залишилося до закінчення перетворення зображення (Рисунок 2.3).

Рисунок 2.1 Головне вікно програми

Далі ми вибираємо фото для стиснення (Рисунок 2.2).

Рисунок 2.2 Вибір фото для стиснення

Рисунок 2.3 Кількість часу , який залишився до кінця стиснення

Після того , як ми діждемося кінця стиснення , ми можемо переглянути результат (Рисунок 2.4).

Рисунок 2.4 Результат стисненого зображення

Після цього ми можемо переглянути розмір у байтах(Рисунок 2.5).

Рисунок 2.5 Розмір у байтах

Також ми можемо зберегти отримане після стиснення алгоритмом зображення у IFS форматі(Рисунок 2.6).

Рисунок 2.6 Збереження зображення у IFS форматі

Ще один приклад з стисненням зображення (Рисунок 2.7).

Рисунок 2.7 Приклад з стисненням іншого зображення

Рисунок 2.8 Результат стисненого зображення

unit FractalCompression;, Messages, SysUtils, Graphics, Classes;

type

// Описание одного региона в выходном файле составляет всего-навсего 6 байт

// Таким образом размер файла = Кол-во регионов * 6= packed record, DomCoordY: Word; // Координаты левого верхнего угла домена, FormNum: Byte; // Различие в яркости, Номер преобразования

end;= packed record: Integer; // Усредненная цветояркость

Ifs: TIfsRec; // Параметры, вычисляемые при компрессии

end;= packed record: Integer; // Усредненная цветояркость;

// Заголовок файла (8 байт)= packed record: array[1..3] of Char;: Byte; // Размер региона

XRegions, YRegions: Word; // Кол-во регионов по Х и У;

// Типы афинных преобразований

TTransformType = (ttRot0, ttRot90, ttRot180, ttRot270, ttSimmX, ttSimmY, ttSimmDiag1, ttSimmDiag2);

TProgressProc = procedure(Percent: Integer; TimeRemain: Cardinal) of Object;= class(TComponent): PByteArray; // Пиксели изображения после преобразования в серый

DomainImage: PByteArray;// Массив пикселей доменного изображения: Integer; // Ширина изображения: Integer; // Высота изображения: Integer; // Размер региона: Integer; // Смещение доменов

Regions: array of array of TRegionRec; // Информация о регионах: array of array of TDomainRec; // Информация о доменах

FGamma: Real;: Integer; // Максимально допустимый размер изображения: Boolean;: Boolean; // Проверяет, была ли выполнена компрессия (загружены ли IFS-данные): Integer; // Размер региона при сжатии

{Очищает данные}ClearData;

{Генерирует исключительную ситуация с сообщением Msg}

procedure Error(Msg: string; Args: array of const);

{Создает массив ссылок Regions на регионы }CreateRegions;

{По исходному изображению SourImage создает доменное изображение}CreateDomainImage;

{Создает массив 2-мерный Domains, в который заносится усредненная цветояркость

для каждого домена}CreateDomains;

{Определяет усредненную яркость для участка Image с началом в т. (X, Y)}

function GetMeanBrigth(Image: PByteArray; X, Y, Width: Integer): Byte;

function XRegions: Integer; // Число регионов по ХYRegions: Integer; // Число регионов по УXDomains: Integer; // Число доменов по ХYDomains: Integer; // Число доменов по У

function DomainImageWidth: Integer; // Ширина доменного изображениSetGamma(const Value: Real);SetMaxImageSize(const Value: Integer);SetRegionSize(const Value: Integer);SetDomainOffset(const Value: Integer);

{Трансформирует заданный регион в соотв. с TransformType. Пиксели в

заданном регионе должны идти друг за другом}

procedure TransformRegion(Sour, Dest: PByteArray; TransformType: TTransformType);

{Возвращает разницу (метрическое расстояние) между регионом и доменом}

{Копирует указанный регион из массива AllImage в массив Dest.

Width - ширина массива AllImage}CopyRegion(AllImage, Dest: PByteArray; X, Y, Width: Integer);GetPixel(X, Y: Integer): Byte;Create(AOwner: TComponent); override;Destroy; override;

{Выполняет собственно само сжатие. При UseAllTransform будут выполнены

все афинные преобразования: поворот и симметрая. В противном случае

будет выполнен только поворот}

procedure Compress(UseAllTransform: Boolean = True; BackProc: TProgressProc = nil);

{Принудительно прерывает процесс фрактального сжатия}Stop;

{Выполняет распаковку изображения. IterCount - кол-во итераций распаковки,- размер региона с распакованном изображении. Если эта величина

такая же, как RegionSize при сжатии, то размер изображение будет как при сжатии.

При уменьшении RegSize распакованное изображение уменьшается и наоборот}

procedure Decompress(IterCount: Integer = 15; RegSize: Integer = 0);

{Строит изображение по доменам. Можно использовать сразу после сжатия для того,

чтобы проверить качество сжатия. Изображение, построенное по доменам,

похоже на восстановленное изображение, только имеет большую контрастность}BuildImageWithDomains;

{Проверяет, была ли выполнена компрессия (загружены ли IFS-данные, необходимые

для декомпрессии). Если IfsIsLoad=True, то можно смело делать декомпрессию}

property IfsIsLoad: Boolean read FIfsIsLoad;

{Ширина изображения (исходного, построенного по доменам, или распакованного)}

property ImageWidth: Integer read SourWidth;

{Высота изображения (исходного, построенного по доменам, или распакованного)}

property ImageHeight: Integer read SourHeight;

{Возвращает значение яркости для указанного пикселя}

property Pixel[X, Y: Integer]: Byte read GetPixel;

{Загружает полноцветное изображение TBitMap для дальнейшей компрессии}LoadImage(Image: TBitmap);

{Рисует изображение на переданном TBitmap. При Regions = True рисуется исходное

изображение, иначе рисуется доменное изображение (оно такое же, только

в 4 раза меньше по площади)}

procedure DrawImage(Image: TBitmap; Regions: Boolean = True);

{Сохраняет результат сжатия в двоичный файл}SaveToFile(FileName: string);

{Выполняет загрузку данных из двоичного файла}LoadFromFile(FileName: string);

{Определяет, какой размер будет у IFS-файла после компрессии}

function GetIFSFileSize(): Cardinal;

{Устанавливает размер региона}RegionSize: Integer read FRegionSize write SetRegionSize;

{Величина смещения домена. По умолчанию = 1 (это число соответствует

доменному изображению, которое в 4 раза меньше исходного)}

property DomainOffset: Integer read FDomainOffset write SetDomainOffset;

{Цветовой коэффициент Гамма}Gamma: Real read FGamma write SetGamma;

{Максимальный размер изображения}MaxImageSize: Integer read FMaxImageSize write SetMaxImageSize;;Register;Register;('Samples', [TFractal]);;

{ TFractal }TFractal.ClearData;Assigned(SourImage) then FreeMem(SourImage);Assigned(DomainImage) then FreeMem(DomainImage);:= nil;:= nil;:= 0;:= 0;:= nil;:= nil;;TFractal.Compress(UseAllTransform: Boolean = True; BackProc: TProgressProc = nil);, RegY, DomX, DomY, Error, BestError, Betta, TransNum, TransCount: Integer;, BaseRegion: PByteArray;, DCoordY, BestFormNum, BestDomX, BestDomY, BestBetta: Integer;: Real;, OneRegTime, AllRegTime: Cardinal;;:= False;:= False;:= RegionSize;UseAllTransform then TransCount := 8 else TransCount := 4;SourImage = nil thenException.Create('Изображение для фрактального сжатия еще не загружено!');;;(BaseRegion, RegionSize * RegionSize);(Region, RegionSize * RegionSize);:= 0;:= 0;:= GetTickCount;

// Перебираем регионыRegY := 0 to YRegions - 1 doRegX := 0 to XRegions - 1 doRegY * XRegions + RegX > 10 then Tc := GetTickCount;:= (RegY * XRegions + RegX) / (YRegions * XRegions) * 100;:= $7FFFFFFF;:= -1;:= -1;:= -1;:= 0;(SourImage, BaseRegion, RegX * RegionSize, RegY * RegionSize, SourWidth);

// Перебираем доменыDomY := 0 to YDomains - 1 doDomX := 0 to XDomains - 1 do

// Определяем разницу в яркости. Она всегда одна для любых трансформаций.

Betta := Regions[RegX, RegY].MeanColor - Domains[DomX, DomY].MeanColor;:= DomX * DomainOffset;:= DomY * DomainOffset;

// Проходим цикл по трансформациямTransNum := 0 to TransCount - 1 do

// Выполняем афинное преобразование(BaseRegion, Region, TTransformType(TransNum));

// Определяем величину разницы между изображениями:= GetDifference(Region, DCoordX, DCoordY, Betta);

// Запоминаем во временные переменные лучшие показатели

if Error < BestError then:= Error;:= TransNum;:= DCoordX;:= DCoordY;:= Betta;;FStop then goto LExit; // Мгновенная реакция на команду выхода Stop

end; // Цикл по трансформациям; // Цикл по доменам

// Для каждого домена определяем его координаты и усредненную яркость

for Y := 0 to YDomains - 1 doX := 0 to XDomains - 1 do[X, Y].MeanColor := GetMeanBrigth(DomainImage, X * DomainOffset,* DomainOffset, DomainImageWidth);;TFractal.CreateRegions;, Y: Integer;:= nil;

SetLength(Regions, XRegions, YRegions);

// Для каждого региона определяем его координаты и усредненную яркость

for Y := 0 to YRegions - 1 doX := 0 to XRegions - 1 do[X, Y].MeanColor := GetMeanBrigth(SourImage, X * RegionSize, Y * RegionSize, SourWidth);;TFractal.Destroy;();;;TFractal.DrawImage(Image: TBitmap; Regions: Boolean = True);, Y, Pixel: Integer;: HDC;SourWidth * SourHeight < 1 then

Error('Ошибка отрисовки изображения!', []);

Image.Width := SourWidth;.Height := SourHeight;:= Image.Canvas.Handle;Y := 0 to SourHeight - 1 doX := 0 to SourWidth - 1 do:= SourImage[Y * SourWidth + X];:= (Pixel shl 16) + (Pixel shl 8) + Pixel;(Handle, X, Y, Pixel);;;not Regions thenY := 0 to SourHeight div 2 - 1 doX := 0 to SourWidth div 2 - 1 do:= DomainImage[Y * DomainImageWidth + X];:= (Pixel shl 16) + (Pixel shl 8) + Pixel;(Handle, X, Y, Pixel);;;;TFractal.Error(Msg: string; Args: array of const);Exception.CreateFmt(Msg, Args);;TFractal.GetMeanBrigth(Image: PByteArray; X, Y, Width: Integer): Byte;, J, Bufer: Integer;:= 0;I := Y to Y + RegionSize - 1 doJ := X to X + RegionSize - 1 do(Bufer, Image[I * Width + J]);:= Trunc(Bufer / (RegionSize * RegionSize));;TFractal.LoadImage(Image: TBitmap);, Y: Integer;: TColor;, green, blue, mask: integer;; // Удаляем массивы:= (Image.Width div RegionSize) * RegionSize;:= (Image.Height div RegionSize) * RegionSize;(SourWidth > MaxImageSize) or (SourWidth < 16) or

(SourHeight > MaxImageSize) or (SourHeight < 16)Error('Недопустимые размеры изображения %d x %d', [Image.Width, Image.Height]);

// ======= Заполняем массив SourImage (для регионов) ===========

// Выделяем память под изображение(SourImage, SourWidth * SourHeight);

// Делаем пиксели серыми и сохраняем их в строковом массиве SourImage

mask := $000000FF;Y := 0 to SourHeight - 1 doX := 0 to SourWidth - 1 do:= Image.Canvas.Pixels[X, Y]; // Определяем цвет пикселя:= (PixColor shr 16) and mask;:= (PixColor shr 8) and mask;:= PixColor and mask;[Y * SourWidth + X] := Byte((red + green + blue) div 3);

end;

// Теперь все пиксели стали серыми.

// ======= Заполняем массив DomenImage (для доменов) ===========

// Вообще-то домены в 2 раза больше регионов, однако из-за этого их сложно сравнивать.

// А вот если мы доменное изображение уменьшим в 4 раза (по площади), то

// размер 1 домена станет равным размеру 1 региона, что гораздо лучше

// и экономнее.;:= False;;TFractal.SetDomainOffset(const Value: Integer);(Value < 1) or (Value > 32) then

Error('Задана недопустимая величина смещения домена %d', [Value]);

FDomainOffset := Value;;TFractal.SetGamma(const Value: Real);(Value < 0.1) or (Value > 1) then

FGamma := Value;;TFractal.SetMaxImageSize(const Value: Integer);:= Value;;TFractal.SetRegionSize(const Value: Integer);(Value < 2) or (Value > 64) then

Error('Задано недопустимое значение региона %d', [Value]);

FRegionSize := Value;;TFractal.XDomains: Integer;:= SourWidth div (2 * DomainOffset) - 1;

if Result <= 1 then('Недопустимое количество доменов по Х %d', [Result]);

end;TFractal.YDomains: Integer;:= SourHeight div (2 * DomainOffset) - 1;

if Result <= 1 then('Недопустимое количество доменов по Y %d', [Result]);

end;TFractal.XRegions: Integer;:= SourWidth div RegionSize;;TFractal.YRegions: Integer;:= SourHeight div RegionSize;;TFractal.TransformRegion(Sour, Dest: PByteArray; TransformType: TTransformType);, J: Integer;TransformType of: // Поворот на 0 градусовI := 0 to RegionSize - 1 doJ := 0 to RegionSize - 1 do[I * RegionSize + J] := Sour[I * RegionSize + J];

end;: // Поворот на 90 градусов

begin

for I := 0 to RegionSize - 1 doJ := 0 to RegionSize - 1 do[(RegionSize - 1 - J) * RegionSize + I] := Sour[I * RegionSize + J];

end;: // Поворот на 180 градусов

begin

for I := 0 to RegionSize - 1 doJ := 0 to RegionSize - 1 do[(RegionSize - 1 - I) * RegionSize + (RegionSize - 1 - J)] := Sour[I * RegionSize + J];

end;: // Поворот на 270 градусов

begin

for I := 0 to RegionSize - 1 doJ := 0 to RegionSize - 1 do[J * RegionSize + (RegionSize - 1 - I)] := Sour[I * RegionSize + J];

end;: // Симметрия относительно Х

begin

for I := 0 to RegionSize - 1 doJ := 0 to RegionSize - 1 do[(RegionSize - 1 - I) * RegionSize + J] := Sour[I * RegionSize + J];

end;: // Симметрия относительно У

begin

for I := 0 to RegionSize - 1 doJ := 0 to RegionSize - 1 do[I * RegionSize + (RegionSize - 1 - J)] := Sour[I * RegionSize + J];

end;: // Симметрия от. главной диагонали

beginI := 0 to RegionSize - 1 doJ := 0 to RegionSize - 1 do[J * RegionSize + I] := Sour[I * RegionSize + J];

end;: // Симметрия от. второстепенной диагонали

beginI := 0 to RegionSize - 1 doJ := 0 to RegionSize - 1 do[(RegionSize - 1 - J) * RegionSize + (RegionSize - 1 - I)] := Sour[I * RegionSize + J];;;;TFractal.DomainImageWidth: Integer;:= SourWidth div 2;;TFractal.LoadFromFile(FileName: string);, Y: Integer;: TIfsHeader;not FileExists(FileName) then

Error('Файл "%s" не существует', [FileName]);

with TMemoryStream.Create do(FileName);(0, soFromBeginning);(Header, SizeOf(TIfsHeader));Header.FileExt <> 'IFS' then;('Файл "%s" имеет недопустимый формат!', [FileName]);;:= Header.XRegions * Header.RegSize;:= Header.YRegions * Header.RegSize;:= Header.RegSize;:= nil;(Regions, XRegions, YRegions);Y := 0 to YRegions - 1 doX := 0 to XRegions - 1 do(Regions[X, Y].Ifs, SizeOf(TIfsRec));

Free;;

// Нужен для масштабирования при декомпрессии

FBaseRegionSize := RegionSize;:= True;;TFractal.SaveToFile(FileName: string);, Y: Integer;: TIfsHeader;Regions = nil then('Сжатие изображения не выполнено!', []);FileExists(FileName) and not DeleteFile(FileName) then

Error('Невозможно удалить файл %s. Возможно он используется другим приложением' +

'или доступен только для чтения.', [FileName]);

Header.FileExt := 'IFS';.RegSize := RegionSize;.XRegions := XRegions;.YRegions := YRegions;TMemoryStream.Create() do

// Сохраняем заголовочную информацию(Header, SizeOf(TIfsHeader));Y := 0 to YRegions - 1 doX := 0 to XRegions - 1 do(Regions[X, Y].Ifs, SizeOf(TIfsRec));(FileName);;

Error('Произошла ошибка при сохранении в файл "%s"', [FileName]);

end;;;;TFractal.Decompress(IterCount: Integer = 15; RegSize: Integer = 0);, J, X, Y, Pixel, Iter: Integer;, Domain2: PByteArray;: Real;

begin

// Массив Region должен быть уже заполненным.not FIfsIsLoad then('Данные, необходимые для декомпрессии, не загружены!', []);

Scale := 1;RegSize >= 2 then:= XRegions * RegSize;:= YRegions * RegSize;:= FBaseRegionSize / RegSize; := RegSize;;

// Создаем серое изображение.

if Assigned(SourImage) then FreeMem(SourImage);(SourImage, SourWidth * SourHeight);

// Делаем пиксели серыми и сохраняем их в строковом массиве SourImageI := 0 to SourHeight * SourWidth - 1 do SourImage[I] := 127;Iter := 1 to IterCount do

// Создаем доменное изображение;

// Доменное и регионное изображения создали

// Проходим по всем регионамJ := 0 to YRegions - 1 do

for I := 0 to XRegions - 1 do

// Запоминаем соответствующий домен, чтобы над ним можно было выполнить преобразования

GetMem(Domain1, RegionSize * RegionSize);(Domain2, RegionSize * RegionSize);(DomainImage, Domain1,(Regions[I, J].Ifs.DomCoordX / Scale),(Regions[I, J].Ifs.DomCoordY / Scale), DomainImageWidth);

// Выполняем заданное преобразование(Domain1, Domain2, TTransformType(Regions[I, J].Ifs.FormNum));

// Изменяем пиксели текущего регионаY := 0 to RegionSize - 1 doX := 0 to RegionSize - 1 do:= Domain2[Y * RegionSize + X] + Regions[I, J].Ifs.Betta;[(J * RegionSize + Y) * SourWidth + I * RegionSize + X] := Pixel;;TFractal.CreateDomainImage;, Y, PixColor: Integer;Assigned(DomainImage) then FreeMem(DomainImage);(DomainImage, SourWidth * SourHeight div 4);Y := 0 to SourHeight div 2 - 1 doX := 0 to SourWidth div 2 - 1 do

begin

// Определяем усредненный цвет пикселя (по цветам 4-х соседних пикселей)

PixColor :=[Y * 2 * SourWidth + X * 2] + SourImage[Y * 2 * SourWidth + X * 2 + 1] +[(Y * 2 + 1) * SourWidth + X * 2] + SourImage[(Y * 2 + 1) * SourWidth + X * 2 + 1];[Y * DomainImageWidth + X] := Trunc(PixColor / 4 * Gamma);;;TFractal.GetDifference(Region: PByteArray; DomCoordX,, Betta: Integer): Integer;, Y, Diff: Integer;:= 0;Y := 0 to RegionSize - 1 doX := 0 to RegionSize - 1 do:= Region[Y * RegionSize + X] -[(DomCoordY + Y) * DomainImageWidth + DomCoordX + X];(Result, Sqr(Abs(Diff - Betta)));;;TFractal.CopyRegion(AllImage, Dest: PByteArray; X, Y,: Integer);, J: Integer;I := 0 to RegionSize - 1 doJ := 0 to RegionSize - 1 do[I * RegionSize + J] := AllImage[(Y + I) * Width + X + J];;TFractal.BuildImageWithDomains;, J, X, Y: Integer;, Domain2: PByteArray;not FIfsIsLoad then

Error('Данные, необходимые для восстановления по доменам, не загружены!', []);

for J := 0 to YRegions - 1 doI := 0 to XRegions - 1 do(Domain1, RegionSize * RegionSize);(Domain2, RegionSize * RegionSize);

// Копируем домен(DomainImage, Domain1, Regions[I, J].Ifs.DomCoordX,[I, J].Ifs.DomCoordY, DomainImageWidth);

// Выполняем афинное преобразование(Domain1, Domain2, TTransformType(Regions[I, J].Ifs.FormNum));

// Копируем домен в регионY := 0 to RegionSize - 1 doX := 0 to RegionSize - 1 do[(J * RegionSize + Y) * SourWidth + I * RegionSize + X] :=[Y * RegionSize + X] + Regions[I, J].Ifs.Betta;(Domain1);(Domain2);;;

TFractal.Stop;:= True;;TFractal.GetPixel(X, Y: Integer): Byte;:= SourImage[Y * SourWidth + X];;TFractal.GetIFSFileSize: Cardinal;:= (ImageWidth div RegionSize) * (ImageHeight div RegionSize) * SizeOf(TIfsRec);Result > 0 then Inc(Result, SizeOf(TIfsHeader));

end;

end.

 

 

 

ВИСНОВКИ


Для виконання курсової роботи використовувався фрактальний алгоритм стиснення. За вхідні дані для моєї програми підходять зображення у форматі BMP з розміром не більше ніж 512х512. Створену мною програма не є ідеальним рішенням , але її можна використовувати для стиснення зображень. З обґрунтування теми моєї курсової роботи можна сказати , що витіснення найбільш популярного і більш використованого алгоритму JPEG , фрактальний алгоритм в повсюдному використанні витіснить його ще не скоро (хоча б в силу низької швидкості архівації останнього), проте в області додатків мультимедіа, в комп'ютерних іграх його використання цілком виправдано.

 

СПИСОК ВИКОРИСТАНОЇ ЛІТЕРАТУРИ


1. ГОСТ 19.201-78. Техническое задание. требования к содержанию и оформлению [Електронний ресурс]. Режим доступу: http://infostart.ru/public/13769/

2. Алгоритм фрактального сжатия [Електронний ресурс]. - Режим доступу : https://ru.wikipedia.org/wiki/Алгоритм_фрактального_сжатия

3.      Лутц, М. Треугольник Серпинского [Електронний ресурс]. - Режим доступу :, http://fractalworld.xaoc.ru/sierpinski_triangle

4.      Калугин Е. Обзор алгоритмов сжатия с потерями [Електронний ресурс]. - Режим доступу : http://mf.grsu.by/UchProc/livak/en/po/theory_fractal.html

5. Аффинное преобразование [Електронний ресурс]. - Режим доступу: https://ru.wikipedia.org/wiki/Афинное_преобразование.

6. Ватолин Д.С. Алгоритмы сжатия изображений. Методическое пособие. [Електронний ресурс]. - Режим доступу : http://lib.ru/TECHBOOKS/ALGO/VATOLIN/algcomp.htm#_Toc448152512

7.      А.Прохоров . Сжатие информации с потерями и без потерь [Електронний ресурс]. - Режим доступу : http://compress.ru/article.aspx?id=10581

Похожие работы на - Алгоритм стиснення з втратами. Фрактальний алгоритм

 

Не нашли материал для своей работы?
Поможем написать уникальную работу
Без плагиата!