Я собрал мозаику из 2025 выстрелов в голову от аватаров лучших пользователей Stack Overflow .
(Нажмите на изображение, чтобы посмотреть его в полном размере.)
Ваша задача - написать алгоритм, который создаст точную фотомозаику другого изображения, используя аватары 48 × 48 пикселей из этой сетки 45 × 45.
Тестовые изображения
Вот тестовые изображения. Первая, конечно же, лампочка!
(Они не являются полноразмерными. Нажмите на изображение, чтобы просмотреть его в полном размере. Половинные версии доступны для Поцелуя , Воскресного полудня ... , Стива Джобса и сфер .)
Спасибо Википедии за все, кроме лучевых трасс.
В полноразмерном виде все эти изображения имеют размеры, кратные 48. Более крупные из них должны были быть в формате JPEG, чтобы они могли быть достаточно сжаты для загрузки.
счет
Это конкурс популярности. За представление с мозаиками, которые наиболее точно изображают исходные изображения, следует проголосовать. Я приму ответ с наибольшим количеством голосов через неделю или две.
правила
Ваша фотомозаика должна быть полностью составлена из неизмененных аватаров 48 × 48 пикселей, взятых из мозаики выше, расположенных в виде сетки.
Вы можете повторно использовать аватар в мозаике. (Действительно, для больших тестовых изображений вам придется.)
Покажите свой вывод, но имейте в виду, что тестовые изображения очень большие, и StackExchange позволяет публиковать изображения размером до 2 МБ . Поэтому сожмите свои изображения или разместите их где-нибудь еще и разместите меньшие версии здесь.
Для подтверждения победителя вы должны предоставить PNG-версии вашей лампочки или сферической мозаики. Поэтому я могу проверить их (см. Ниже), чтобы убедиться, что вы не добавляете дополнительные цвета в аватары, чтобы мозаика выглядела лучше.
Validator
Этот скрипт Python можно использовать для проверки, действительно ли в законченной мозаике используются неизмененные аватары. Просто установите toValidate
и allTiles
. Маловероятно, что он будет работать для JPEG или других форматов с потерями, поскольку он сравнивает вещи попиксельно.
from PIL import Image, ImageChops
toValidate = 'test.png' #test.png is the mosaic to validate
allTiles = 'avatars.png' #avatars.png is the grid of 2025 48x48 avatars
def equal(img1, img2):
return ImageChops.difference(img1, img2).getbbox() is None
def getTiles(mosaic, (w, h)):
tiles = {}
for i in range(mosaic.size[0] / w):
for j in range(mosaic.size[1] / h):
x, y = i * w, j * h
tiles[(i, j)] = mosaic.crop((x, y, x + w, y + h))
return tiles
def validateMosaic(mosaic, allTiles, tileSize):
w, h = tileSize
if mosaic.size[0] % w != 0 or mosaic.size[1] % h != 0:
print 'Tiles do not fit mosaic.'
elif allTiles.size[0] % w != 0 or allTiles.size[1] % h != 0:
print 'Tiles do not fit allTiles.'
else:
pool = getTiles(allTiles, tileSize)
tiles = getTiles(mosaic, tileSize)
matches = lambda tile: equal(tiles[pos], tile)
success = True
for pos in tiles:
if not any(map(matches, pool.values())):
print 'Tile in row %s, column %s was not found in allTiles.' % (pos[1] + 1, pos[0] + 1)
success = False
if success:
print 'Mosaic is valid.'
return
print 'MOSAIC IS INVALID!'
validateMosaic(Image.open(toValidate).convert('RGB'), Image.open(allTiles).convert('RGB'), (48, 48))
Удачи всем! Я не могу ждать, чтобы увидеть результаты.
Примечание: я знаю, что алгоритмы фотомозаики легко найти в Интернете, но их еще нет на этом сайте. Я действительно надеюсь, что мы увидим что-то более интересное, чем обычный алгоритм «усреднить каждую плитку и каждое пространство сетки и сопоставить их» .
источник
Ответы:
Ява, среднее расстояние
Алгоритм выполняет поиск по всем ячейкам аватара для каждого пространства сетки отдельно. Из-за небольших размеров я не реализовывал сложные структуры данных или алгоритмы поиска, а просто перебор всего пространства.
Этот код не делает никаких модификаций плиток (например, не адаптируется к цветам назначения).
Полученные результаты
Нажмите для просмотра в полном размере.
Влияние радиуса
С помощью
radius
вы можете уменьшить повторяемость плиток в результате. Установкаradius=0
там не влияет. Например,radius=3
подавляет одну и ту же плитку в радиусе 3 плиток.Радиус = 0
Радиус = 3
Влияние коэффициента масштабирования
Используя
scaling
фактор, мы можем определить, как ищется соответствующий тайл.scaling=1
означает поиск совпадения с точностью до пикселя, в то время какscaling=48
выполняется поиск средней плитки.масштабирование = 48
масштабирование = 16
масштабирование = 4
масштабирование = 1
источник
Mathematica, с контролем гранулярности
При этом используются фотографии размером 48 x 48 пикселей. По умолчанию он заменяет эти пиксели на соответствующий квадрат размером 48x48 пикселей с аппроксимируемого изображения.
Тем не менее, размер квадратов назначения может быть меньше 48 x 48, что позволяет повысить точность детализации. (см. примеры ниже).
Предварительная обработка палитры
collage
это изображение, содержащее фотографии, которые служат палитрой.picsColors
список отдельных фотографий в сочетании с их средним красным, средним зеленым и синим значениями.пример
Давайте найдем фотографию, которая лучше всего соответствует RGBColor [0.640, 0.134, 0.249]:
фотомозаику
`photoMosaic использует исходную картинку, из которой мы сделаем фото-мозаику.
targetPic
удалит четвертый параметр (PNG и некоторые JPG), оставив только R, G, B.dims
размерыtargetPic
.tiles
маленькие квадраты, которые вместе составляют целевую картинку.targetSwathSize is the granularity parameter; it defaults at 48 (x48).
tileReplacements
фотографии, которые соответствуют каждой плитке, в правильном порядке.gallery
является набором замены плиток (фотографий) с правильной размерностью (то есть количеством строк и столбцов, которые соответствуют плиткам).ImageAssembly
объединяет мозаику в непрерывное изображение на выходе.Примеры
Это заменяет каждый квадрат 12x12 на изображении в воскресенье соответствующей фотографией 48 x 48 пикселей, которая лучше всего соответствует среднему цвету.
Воскресенье (подробно)
Деталь, стевджобс.
Деталь поцелуя:
источник
JS
То же, что и в предыдущем гольфе: http://jsfiddle.net/eithe/J7jEk/ : D
(на этот раз вызывается с помощью
unique: false, {pixel_2: {width: 48, height: 48}, pixel_1: {width: 48, height: 48}}
) (не обрабатывайте палитру, чтобы использовать один пиксель один раз, пиксели палитры - образцы 48x48, пиксели формы - образцы 48x48).В настоящее время он просматривает список аватаров, чтобы найти ближайшее совпадение по массе выбранного алгоритма, однако он не выполняет сопоставления однородности цвета (на что мне нужно взглянуть.
К сожалению, я не могу поиграть с большими изображениями, потому что у меня заканчивается ОЗУ: D Если возможно, я буду признателен за меньшие выходные изображения. Если используется 1/2 размера изображения, вот воскресенье днем:
источник
GLSL
Разница между этим вызовом и вызовом американской готики в палитре Моны Лизы: переставьте пиксели меня заинтересовали, потому что мозаичные плитки можно использовать повторно, а пиксели - нет. Это означает, что можно легко распараллелить алгоритм, поэтому я решил попробовать массивно параллельную версию. Под «массовым использованием» я подразумеваю использование 1344 шейдерных ядер на GTX670 моего рабочего стола одновременно, через GLSL.
метод
Фактическое сопоставление мозаики простое: я вычисляю расстояние RGB между каждым пикселем в целевой области и мозаичной плиткой и выбираю плитку с наименьшей разницей (взвешенной по значениям яркости). Индекс плитки записывается в атрибутах фрагмента красного и зеленого цвета, а затем после того, как все фрагменты были отрисованы, я считываю значения обратно из кадрового буфера и формирую выходное изображение из этих индексов. Реальная реализация довольно взломана; вместо создания FBO я просто открыл окно и отрисовал его, но GLFW не может открывать окна при сколь угодно малых разрешениях, поэтому я создаю окно больше, чем требуется, а затем рисую маленький прямоугольник, который имеет правильный размер, чтобы он имел один фрагмент на плитку, которая отображается на исходное изображение. Полное решение MSVC2013 доступно по адресуhttps://bitbucket.org/Gibgezr/mosaicmaker Для компиляции требуется GLFW / FreeImage / GLEW / GLM и для запуска OpenGL 3.3 или более поздние драйверы / видеокарта.
Источник шейдера фрагмента
Полученные результаты
Изображения отображаются почти мгновенно, поэтому распараллеливание прошло успешно. Недостатком является то, что я не могу заставить отдельные фрагменты полагаться на выходные данные любых других фрагментов, поэтому нет никакого способа получить существенное повышение качества, которое вы можете получить, не выбирая одну и ту же плитку дважды в пределах определенного диапазона. Итак, быстрые результаты, но ограниченное качество из-за массовых повторений плиток. В общем, было весело. http://imgur.com/a/M0Db0 для полноразмерных версий.
источник
питон
Здесь идет речь о первом решении Python, используя средний подход. Мы можем развиваться отсюда. Остальные изображения здесь .
источник
Еще одно решение Python - на основе среднего (RGB против L a b *)
Результаты (есть небольшие отличия)
Лампа - RGB
полный обзор
Лампа - Лаборатория
полный обзор
Стив - RGB
полный обзор
Стив - Лаб
полный обзор
Сферы - RGB
полный обзор
Сферы - Лаборатория
полный обзор
Воскресенье - RGB
полный обзор
Воскресенье - лаборатория
полный обзор
Поцелуй - RGB
полный обзор
Kiss - Lab
полный обзор
Код
требует python-colormath для лаборатории
источник