Генерация фотографической мозаики из заданного набора миниатюр
Фотографическая мозаика - это метод воссоздания существующего изображения в виде мозаики миниатюр. Цвет исходных пикселей должен примерно соответствовать цвету покрывающей плитки.
Например, ролевый геймер заново сгенерировал карту мира из миниатюрных изображений пользователей.
Исходный код этого изображения предоставлен на github, но он довольно приспособлен для конкретной задачи карты мира.
Существует ли общее решение для повторного создания существующего изображения в виде коллажа / мозаики из набора заданных миниатюр?
1 ответ
Доказательство концепции следует, как простой bash
Скрипт с ImageMagick для выполнения обработки изображения.
#!/bin/bash
# Take all JPEGS in current directory and get their average RGB color and name in "tiles.txt"
for f in *.jpg; do convert $f -depth 8 -resize 1x1! -format "%[fx:int(mean.r*255)] %[fx:int(mean.g*255)] %[fx:int(mean.b*255)] $f\n" info: ; done > tiles.txt
# Create empty black output canvas same size as original map
convert map.png -threshold 100% result.png
# Split map into tiles of 10x10 and get x,y coordinates of each tile and the average RGB colour
convert map.png -depth 8 -crop 10x10 -format "%X %Y %[fx:int(mean.r*255)] %[fx:int(mean.g*255)] %[fx:int(mean.b*255)]\n" info: |
while read x y r g b; do
thumb=$(awk -v R=$r -v G=$g -v B=$b '
NR==1{nearest=3*255*255*255;tile=$4}
{
tr=$1;tg=$2;tb=$3
# Calculate distance (squared actually but sqrt is slow)
d=((R-tr)*(R-tr))+((G-tg)*(G-tg))+((B-tb)*(B-tb))
if(d<nearest){nearest=d;tile=$4}
}
END{print tile}
' tiles.txt)
echo $x $y $r $g $b $thumb
convert result.png -draw "image copy $x,$y 10,10 \"$thumb\"" result.png
done
У меня нет бесконечных запасов миниатюр, но концепция, кажется, работает. Математика расстояния между цветами делается в awk
и, очевидно, это можно сделать в более однородном воспринимаемом цветовом пространстве, а также можно значительно ускорить процесс. Другая мысль, чтобы избежать повторения, может состоять в том, чтобы складывать плитки в одинаковые цвета, а затем выбирать случайным образом один из ближайшего, а не абсолютного ближайшего.
Файл tiles.txt
выглядит так:
111 116 109 0.jpg
82 88 81 1.jpg
112 110 95 10.jpg
178 154 150 100.jpg
190 169 163 101.jpg
187 166 163 102.jpg
...
...