Создаем мозаику из случайных изображений

Отредактировано

14К открытий14К показов
Создаем мозаику из случайных изображений

Рассказывает Чарльз Ньюи, автор блога blog.assemblyco.de

Если вы следили за новинками современного искусства, вы наверняка видели что-то, похожее на это:

Создаем мозаику из случайных изображений 1

Или это:

Создаем мозаику из случайных изображений 2

Да, это действительно лицо Барака Обамы, выложенное мозаикой из тостов различной прожарки.

Недавно я захотел создать что-то похожее, используя набор случайных изображений. Я планировал напечатать несколько картинок и создать из них, например, постер. Однако процесс поиска достаточного большого и разнообразного количества картинок и их расстановки очень трудоемок, а я слишком ленив, чтобы делать это вручную.

К счастью, если вы знаете Python, работа сильно упрощается. Я знаю, поэтому давайте приступим. Наш мини-проект состоит из двух шагов: сбор и обработка набора изображений и их расстановка в виде мозаики.

Шаг 1: поиск и обработка изображений

Я не знал, откуда можно было бы взять картинки — может, из Wikipedia Commons или Flickr? Может, вообще из каких-либо публичных источников? В итоге было решено использовать Flickr. Я написал простенький скрипт на Python, который ищет на Flickr изображения, используя определенный набор тегов (и фильтруя их по наличию лицензии Creative Commons, разумеется), и скачивает их. Другой скрипт обрезает картинки до клеток размера 32х32. Теперь, когда все наши картинки одного размера, их можно использовать в мозаике.

В итоге я скачал и обработал около 500 изображений из Flickr. Это очень небольшой набор, поэтому я не рассчитывал, что результат будет очень хорошим — но в итоге я был приятно удивлен.

Шаг 2: составление мозаики

Этот этап абсолютно прямолинеен. Вот простой алгоритм для расстановки изображений:

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

Определение наиболее подходящей картинки

Это тоже очень просто. Поскольку это было самым простым вариантом, я усреднил каждый канал цвета по всему изображению и предположил, что получившийся цвет будет каноническим для всего изображения.

Подбор лучшей картинки из набора производится в лоб — достаточно любым способом (я использовал манхэттенское расстояние) вычислить расстояние между каждым каналом цвета между пикселем и средним цветом картинки и отсортировать картинки по расстоянию. Первая будет лучшим вариантом. Элементарно.

Результат

Я немного поэкспериментировал, чтобы понять, работает ли мой алгоритм. Удивительно, но он работал достаточно неплохо, хотя, как я и думал, в нем было очень много одинаковых изображений, что портило эффект. Продемонстрирую это, используя фото президента Обамы, раз уж мы упоминали его ранее.

Вот как выглядит исходное изображение:

Создаем мозаику из случайных изображений 3

Первая попытка была успешной — вот что получилось:

Создаем мозаику из случайных изображений 4

Ура, все работает!… но многочисленные повторы одинаковых картинок режут глаз. А что, если выбирать не наиболее подходящую картинку, а одну из пяти наиболее подходящих?

Создаем мозаику из случайных изображений 5

Гораздо лучше! Так точно интереснее. Для закрепления попробуем еще одно лицо — как насчет Мишель Обамы?

Создаем мозаику из случайных изображений 6

Отлично. Как насчет (черт, Обамы кончились)… ммм… как насчет моего лица?

Вот как я выгляжу:

Создаем мозаику из случайных изображений 7

А вот получившаяся мозаика:

Создаем мозаику из случайных изображений 8

Успех! Неплохо для пары дней работы. Если это вас заинтересовало, исходный код можно найти на моем GitHub.

Следите за новыми постами
Следите за новыми постами по любимым темам
14К открытий14К показов