Создаем мозаику из случайных изображений
14К открытий14К показов
Рассказывает Чарльз Ньюи, автор блога blog.assemblyco.de
Если вы следили за новинками современного искусства, вы наверняка видели что-то, похожее на это:
Или это:
Да, это действительно лицо Барака Обамы, выложенное мозаикой из тостов различной прожарки.
Недавно я захотел создать что-то похожее, используя набор случайных изображений. Я планировал напечатать несколько картинок и создать из них, например, постер. Однако процесс поиска достаточного большого и разнообразного количества картинок и их расстановки очень трудоемок, а я слишком ленив, чтобы делать это вручную.
К счастью, если вы знаете Python, работа сильно упрощается. Я знаю, поэтому давайте приступим. Наш мини-проект состоит из двух шагов: сбор и обработка набора изображений и их расстановка в виде мозаики.
Шаг 1: поиск и обработка изображений
Я не знал, откуда можно было бы взять картинки — может, из Wikipedia Commons или Flickr? Может, вообще из каких-либо публичных источников? В итоге было решено использовать Flickr. Я написал простенький скрипт на Python, который ищет на Flickr изображения, используя определенный набор тегов (и фильтруя их по наличию лицензии Creative Commons, разумеется), и скачивает их. Другой скрипт обрезает картинки до клеток размера 32х32. Теперь, когда все наши картинки одного размера, их можно использовать в мозаике.
В итоге я скачал и обработал около 500 изображений из Flickr. Это очень небольшой набор, поэтому я не рассчитывал, что результат будет очень хорошим — но в итоге я был приятно удивлен.
Шаг 2: составление мозаики
Этот этап абсолютно прямолинеен. Вот простой алгоритм для расстановки изображений:
- Считать целевое изображение (то,из которого мы хотим сделать мозаику).
- Считать весь набор картинок.
- Для каждой картинки:вычислить средний цвет картинки;сохранить это значение в структуру данных (для последующего использования).
- Создать пустое изображение нужного размера для размещения картинок.
- Для каждого пикселя целевого изображения:получить его цвет в RGB;найти картинку наиболее подходящего среднего цвета;вставить соответствующую картинку в пустое изображение, созданное ранее.
- Сохранить полученное изображение.
Определение наиболее подходящей картинки
Это тоже очень просто. Поскольку это было самым простым вариантом, я усреднил каждый канал цвета по всему изображению и предположил, что получившийся цвет будет каноническим для всего изображения.
Подбор лучшей картинки из набора производится в лоб — достаточно любым способом (я использовал манхэттенское расстояние) вычислить расстояние между каждым каналом цвета между пикселем и средним цветом картинки и отсортировать картинки по расстоянию. Первая будет лучшим вариантом. Элементарно.
Результат
Я немного поэкспериментировал, чтобы понять, работает ли мой алгоритм. Удивительно, но он работал достаточно неплохо, хотя, как я и думал, в нем было очень много одинаковых изображений, что портило эффект. Продемонстрирую это, используя фото президента Обамы, раз уж мы упоминали его ранее.
Вот как выглядит исходное изображение:
Первая попытка была успешной — вот что получилось:
Ура, все работает!… но многочисленные повторы одинаковых картинок режут глаз. А что, если выбирать не наиболее подходящую картинку, а одну из пяти наиболее подходящих?
Гораздо лучше! Так точно интереснее. Для закрепления попробуем еще одно лицо — как насчет Мишель Обамы?
Отлично. Как насчет (черт, Обамы кончились)… ммм… как насчет моего лица?
Вот как я выгляжу:
А вот получившаяся мозаика:
Успех! Неплохо для пары дней работы. Если это вас заинтересовало, исходный код можно найти на моем GitHub.
14К открытий14К показов