Створення фотомозаик з допомогою мови Wolfram Language (Mathematica)


Завантажити переклад у вигляді документа Mathematica, який містить весь код використаний у статті, можна тут (архів, ~3 МБ).

Введення
До Нового 2015-го року залишилося вже менше доби:

In[1]:=

ImageMosaic_2.jpeg

Out[1]=

ImageMosaic_3.jpeg

Мені хотілося б привітати всіх з Наступаючим Новим 2015-м роком і розповісти про те, як ви можете зробити своїм близьким незвичайний подарунок у вигляді фотомозаики, створеної за допомогою системи Mathematica 10 і мови Wolfram Language.

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

Для того, щоб створити фотомозаику можна діяти двома основними способами:

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

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

Я не думаю, що мої колекції такого роду будуть дуже цікаві більшості читачів, тому в якості колекції я буду використовувати набір зображень якогось відомого людини. В якості такої людини я візьму того, хто відомий абсолютно всім, а саме — Арнольда Шварценеггера.

Для створення колекції зображень скористаємося парсером з сайту Zimbio:

In[2]:=

ImageMosaic_4.jpeg

In[3]:=

ImageMosaic_5.jpeg

Імпортуємо всі наявні фото з профілю Арнольда:

In[4]:=

ImageMosaic_6.jpeg

Всього було імпортовано 5436 фото:

In[5]:=

ImageMosaic_7.jpeg

Out[5]=

ImageMosaic_8.jpeg

Загальний вага яких дорівнює майже 5 ГБ.

In[6]:=

ImageMosaic_9.jpeg

Out[6]=

ImageMosaic_10.jpeg

Можемо подивитися на колекцію мигцем, склавши колаж з 150 випадково вибраних зображень:

In[7]:=

ImageMosaic_11.jpeg

Out[7]=

<img src=«habrastorage.org/getpro/habr/post_images/992/bf4/75e/992bf475eeab61df8afbc2ccc9f1c946.png» alt=«ImageMosaic_12.jpeg» width=«700» висота=«700»/>

Проста фотомозаика
Приступимо до створення простої фотомозаики.

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

In[8]:=

ImageMosaic_13.jpeg

Тепер подгрузим шляху до кожного з зображень:

In[9]:=

ImageMosaic_14.jpeg

Out[9]//Short=

ImageMosaic_15.jpeg

Збережемо кількість зображень в окремій змінної:

In[10]:=

ImageMosaic_16.jpeg

Out[10]=

ImageMosaic_17.jpeg

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

In[11]:=

ImageMosaic_18.gif

In[13]:=

ImageMosaic_19.jpeg

In[14]:=

ImageMosaic_20.jpeg

Подгрузим шляху до кожної з мініатюр:

In[15]:=

ImageMosaic_21.jpeg

Тепер завантажимо всі мініатюри в систему:

In[16]:=

ImageMosaic_22.jpeg

Обчислимо для кожної з мініатюр її середній RGB колір:

In[17]:=

ImageMosaic_23.jpeg

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

In[18]:=

ImageMosaic_24.gif

Out[18]=

ImageMosaic_25.jpeg

Створимо функцію, складову фотомозаику:

In[20]:=

ImageMosaic_26.jpeg

Задамо зображення, мозаїку якого ми хочемо отримати:

In[21]:=

ImageMosaic_27.jpeg

Подивимося, як буде виглядати мозаїка у разі, якщо береться найближча мініатюра при послідовному зменшенні мініатюр:

In[22]:=

ImageMosaic_28.jpeg

Out[22]=

ImageMosaic_29.jpeg

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

Для того, щоб позбутися від цього, встановимо випадковий вибір з 10 найближчих мініатюр:

In[23]:=

ImageMosaic_30.jpeg

Out[23]=

ImageMosaic_31.jpeg

Безумовно, з допомогою цього алгоритму можна створювати будь-які мозаїки такого роду:

In[24]:=

ImageMosaic_32.jpeg

Out[24]=

<img src=«habrastorage.org/getpro/habr/post_images/533/e38/ea0/533e38ea064345333e227f74baba1ff0.png» alt=«ImageMosaic_33.jpeg» width=«700» висота=«1045»/>

Адаптивна фотомозаика
Створимо функцію, яка буде розбивати зображення на менші зображення адаптивним способом.

Функція adaptiveImagePartition працює наступним чином:

  • вона являє собою итеративное адаптивне розбиття за допомогою кроків, наведених нижче;
  • функція toParts викликає функцію parts стосовно до кожного зображення (або вихідного зображення на першому кроці);
  • функція parts дробить зображення на 4 рівні частини (прямими, проведеними через середини протилежних сторін зображення) і віддає результат функції toParts;
  • для кожного з чотирьох отриманих фрагментів обчислюється її середній колір, після чого шукаються попарні відстані між середніми квітами з допомогою функції ColorDistance (згідно стандарту CIE2000), потім шукається середнє значення відстані. Якщо воно більше значення prec, то початкове зображення замінюється на чотири нових, в іншому разі зображення залишається в колишньому вигляді;
  • до отриманого набору зображень застосовується правило обробки rule.
In[25]:=

ImageMosaic_34.jpeg

In[26]:=

ImageMosaic_35.jpeg

In[27]:=

ImageMosaic_36.jpeg

Задамо базове зображення:

In[28]:=

ImageMosaic_37.jpeg

Подивимося на кроки роботи створеної функції:

In[29]:=

ImageMosaic_38.jpeg

Out[29]=

ImageMosaic_39.jpeg

Змінивши обробник, ми можемо отримати адаптивну пікселізація:

In[30]:=

ImageMosaic_40.jpeg

Out[30]=

ImageMosaic_41.jpeg

Нарешті, якщо в якості обробника вказати заміну фрагмента зображення на найближчу мініатюру, то отримаємо:

In[31]:=

ImageMosaic_42.jpeg

Out[31]=

ImageMosaic_43.jpeg

Висновок
Сподіваюся, що мій пост зміг порадувати вас і зацікавити. Безумовно, можна створити ще більш складні алгоритми для фотомозаик, враховують: не тільки середній колір, але і домінантні кольори фрагментів і мініатюр (DominantColors); морфологію зображень; більш складне адаптивне розбиття та ін. Але, думаю, створених алгоритмів може бути вже цілком достатньо для того, щоб зробити оригінальний подарунок вашим близьким до Наступаючого Нового 2015-го року.

Ресурси для вивчення Wolfram Language (Mathematica) російською мовою: http://habrahabr.ru/post/244451

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.