Створюємо мозаїку з випадкових зображень


Дізнайтесь більше про нові кар'єрні можливості в EchoUA. Цікаві проекти, ринкова оплата, гарний колектив. Надсилайте резюме та приєднуйтеся до нас.

Розповідає Чарльз Ньюї, автор блогу blog.assemblyco.de


Якщо Ви стежили за новинками сучасного мистецтва, то напевно бачили щось, схоже на це:

 

Чи це:

Так, це дійсно обличчя Барака Обами, викладене мозаїкою з тостів різного прожарювання.

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

На щастя, якщо Ви знаєте Python, то робота значно спрощується. Я знаю, тому давайте приступимо. Наш міні-проект складається з двох кроків: 1. Збір і обробка набору зображень і 2. Розставляння їх у вигляді мозаїки.

Крок 1. Пошук і обробка зображень

Я не знав, звідки можна було б узяти картинки. Може, з Wikipedia Commons або Flickr? Може, взагалі з якихось публічних джерел? У результаті було вирішено використати Flickr. Я написав простенький скрипт на Python, який шукає на Flickr зображення, використовуючи певний набір тегів (і фільтруючи їх за наявністю ліцензії Creative Commons, зрозуміло), і скачує їх. Інший скрипт обрізує картинки до клітин розміру 32х32. Тепер, коли всі наші картинки одного розміру, їх можна використати в мозаїці.

Я скачав і обробив близько 500 зображень з Flickr. Це дуже невеликий набір, тому я не розраховував на високий результат, але був приємно здивований.

Крок 2. Складання мозаїки

Цей етап абсолютно прямолінійний. Ось простий алгоритм для розставляння зображень:

  1. Обчислити цільове зображення (те, з якого ми хочемо зробити мозаїку).
  2. Обчислити весь набір картинок.
  3. Для кожної картинки:
    • обчислити середній колір картинки;
    • зберегти це значення в структурі даних (для подальшого використання).
  4. Створити порожнє зображення потрібного розміру для розміщення картинок.
  5. Для кожного пікселя цільового зображення:
    • отримати його колір у RGB;
    • знайти картинку найбільш відповідного середнього кольору;
    • вставити відповідну картинку в порожнє зображення, створене раніше.
  6. Зберегти отримане зображення.

Визначення найбільш відповідної картинки

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

Підбір кращої картинки з набору робиться “в лоб” – достатньо в будь-який спосіб обчислити відстань між кожним каналом кольору між пікселем і середнім кольором картинки і відсортувати картинки за відстанню. Перша буде кращим варіантом. Елементарно.

Результат

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

Ось як виглядає початкове зображення:

Перша спроба була успішною – ось що вийшло:

Чудово, все працює! Проте численні повтори однакових картинок впадають в око. А якщо вибирати не найбільш відповідну картинку, а одну з п’яти найбільш відповідних?

Набагато краще! Так точно цікавіше. Для закріплення спробуємо ще одне обличчя. Як щодо Мішель Обами?

Відмінно. Як щодо (Дідько, Обами закінчилися!). Гм. Як щодо мого обличчя?

Ось як я виглядаю:

А ось мозаїка, що вийшла:

Успіх! Непогано для двох днів роботи. Якщо Вас це зацікавило, то вихідний код можна знайти на моєму GitHub.

Джерело: блог Assemblyco

Київ, Харків, Одеса, Дніпро, Запоріжжя, Кривий Ріг, Вінниця, Херсон, Черкаси, Житомир, Хмельницький, Чернівці, Рівне, Івано-Франківськ, Кременчук, Тернопіль, Луцьк, Ужгород, Кам'янець-Подільський, Стрий - за статистикою саме з цих міст програмісти найбільше переїжджають працювати до Львова. А Ви розглядаєте relocate?


Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *