He compilado un mosaico de 2025 disparos a la cabeza de los avatares de los principales usuarios de Stack Overflow .
(Haga clic en la imagen para verla en tamaño completo).
Su tarea es escribir un algoritmo que cree un fotomosaico preciso de otra imagen utilizando los avatares de 48 × 48 píxeles de esta cuadrícula de 45 × 45 de ellos.
Imágenes de prueba
Aquí están las imágenes de prueba. ¡El primero es, por supuesto, una bombilla!
(No son de tamaño completo aquí. Haga clic en una imagen para verla en tamaño completo. Hay versiones de tamaño medio disponibles para The Kiss , A Sunday Afternoon ... , Steve Jobs y las esferas ).
Gracias a Wikipedia por todas menos las esferas de trazado de rayos.
A tamaño completo, todas estas imágenes tienen dimensiones divisibles por 48. Las más grandes tenían que ser JPEG para que pudieran comprimirse lo suficiente como para cargarlas.
Tanteo
Este es un concurso de popularidad. La presentación con mosaicos que representan con mayor precisión las imágenes originales debe ser votada. Aceptaré la respuesta más votada en una o dos semanas.
Reglas
Sus fotomosaicos deben estar completamente compuestos por avatares inalterados de 48 × 48 píxeles tomados del mosaico de arriba, dispuestos en una cuadrícula.
Puedes reutilizar un avatar en un mosaico. (De hecho, para las imágenes de prueba más grandes tendrá que hacerlo).
Muestre su salida, pero tenga en cuenta que las imágenes de prueba son muy grandes y que StackExchange solo permite publicar imágenes de hasta 2 MB . Así que comprima sus imágenes o guárdelas en otro lugar y ponga versiones más pequeñas aquí.
Para ser confirmado el ganador, debe proporcionar versiones PNG de su bombilla o mosaicos de esferas. Esto es para que pueda validarlos (ver más abajo) para asegurarme de que no agregue colores adicionales a los avatares para que los mosaicos se vean mejor.
Validador
Este script de Python se puede usar para verificar si un mosaico completo realmente usa avatares inalterados. Solo establece toValidate
y allTiles
. Es poco probable que funcione para JPEG u otros formatos con pérdida, ya que compara las cosas exactamente, píxel por píxel.
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))
¡Buena suerte a todos! No puedo esperar para ver los resultados.
Nota: Sé que los algoritmos fotomosaicos son fáciles de encontrar en línea, pero aún no están en este sitio. Realmente espero que veamos algo más interesante que el algoritmo habitual "promedio de cada mosaico y cada espacio de cuadrícula y unirlos" .
fuente
Respuestas:
Java, distancia media
El algoritmo realiza una búsqueda a través de todas las fichas de avatar para cada espacio de cuadrícula por separado. Debido a los pequeños tamaños, no implementé estructuras de datos sofisticadas o algoritmos de búsqueda, sino que simplemente forcé la fuerza bruta en todo el espacio.
Este código no realiza ninguna modificación en los mosaicos (por ejemplo, no se adapta a los colores de destino).
Resultados
Haga clic para obtener una imagen a tamaño completo.
Efecto de radio
Usarlo
radius
puede reducir la repetitividad de los mosaicos en el resultado. La configuraciónradius=0
no tiene ningún efecto. Por ejemplo,radius=3
suprime el mismo mosaico dentro de un radio de 3 mosaicos.radio = 0
radio = 3
Efecto del factor de escala
Usando el
scaling
factor podemos determinar cómo se busca el mosaico coincidente.scaling=1
significa buscar una combinación perfecta de píxeles mientrasscaling=48
hace una búsqueda de mosaico promedio.escala = 48
escala = 16
escala = 4
escala = 1
fuente
Mathematica, con control de granularidad.
Utiliza las fotos de 48 x 48 píxeles, según sea necesario. Por defecto, intercambiará esos píxeles por un cuadrado de 48x48 píxeles correspondiente de la imagen que se aproximará.
Sin embargo, el tamaño de los cuadrados de destino se puede configurar para que sea menor que 48 x 48, lo que permite una mayor fidelidad a los detalles. (ver los ejemplos a continuación).
Preprocesar la paleta
collage
es la imagen que contiene las fotos para servir como paleta.picsColors
es una lista de fotos individuales combinadas con sus valores medios rojo, verde medio y azul medio.Ejemplo
Busquemos la foto que mejor coincida con RGBColor [0.640, 0.134, 0.249]:
photoMosaic
`photoMosaic toma como entrada la imagen en bruto de la que haremos un mosaico fotográfico.
targetPic
eliminará un cuarto parámetro (de PNG y algunos JPG), dejando solo R, G, B.dims
son las dimensiones detargetPic
.tiles
son los pequeños cuadrados que juntos forman la imagen objetivo.targetSwathSize is the granularity parameter; it defaults at 48 (x48).
tileReplacements
son las fotos que coinciden con cada mosaico, en el orden correcto.gallery
es el conjunto de reemplazos de mosaicos (fotos) con la dimensionalidad adecuada (es decir, el número de filas y columnas que coinciden con los mosaicos).ImageAssembly
une el mosaico en una imagen de salida continua.Ejemplos
Esto reemplaza cada cuadrado de 12x12 de la imagen, el domingo, con una fotografía correspondiente de 48 x 48 píxeles que mejor se adapta al color promedio.
Domingo (detalle)
Detalle, stevejobs.
Detalle del beso:
fuente
JS
Igual que en el golf anterior: http://jsfiddle.net/eithe/J7jEk/ : D
(esta vez llamado con
unique: false, {pixel_2: {width: 48, height: 48}, pixel_1: {width: 48, height: 48}}
) (no trate que la paleta use un píxel una vez, los píxeles de la paleta son muestras de 48x48, los píxeles de forma son muestras de 48x48).Actualmente busca en la lista de avatares para encontrar la coincidencia más cercana por peso del algoritmo seleccionado, sin embargo, no realiza ninguna coincidencia de uniformidad de color (algo que necesito echar un vistazo.
Desafortunadamente, no puedo jugar con imágenes más grandes, porque mi RAM se agota: D Si es posible, agradecería imágenes de salida más pequeñas. Si usa la mitad del tamaño de la imagen, aquí está el domingo por la tarde:
fuente
GLSL
La diferencia entre este desafío y el de American Gothic en la paleta de Mona Lisa: reorganizar los píxeles me interesó, porque los mosaicos se pueden reutilizar, mientras que los píxeles no. Esto significa que es posible paralelizar fácilmente el algoritmo, así que decidí intentar una versión paralela masiva. Por "masivamente" me refiero a usar los núcleos de sombreador 1344 en el GTX670 de mi escritorio simultáneamente, a través de GLSL.
Método
La coincidencia real de mosaicos es simple: calculo la distancia RGB entre cada píxel en un área objetivo y el área de mosaicos, y elijo el mosaico con la menor diferencia (ponderado por los valores de brillo). El índice de mosaico se escribe en los atributos de color rojo y verde del fragmento, luego, después de haber procesado todos los fragmentos, leí los valores del framebuffer y construí la imagen de salida a partir de esos índices. La implementación real es un gran truco; en lugar de crear un FBO, acabo de abrir una ventana y la rendericé, pero GLFW no puede abrir ventanas con resoluciones arbitrariamente pequeñas, por lo que creo la ventana más grande de lo necesario, luego dibujo un pequeño rectángulo del tamaño correcto para que tenga un fragmento por mosaico que se asigna a la imagen de origen. Toda la solución MSVC2013 está disponible enhttps://bitbucket.org/Gibgezr/mosaicmaker Requiere GLFW / FreeImage / GLEW / GLM para compilar, y OpenGL 3.3 o mejores controladores / tarjeta de video para funcionar.
Fragmento Shader Source
Resultados
Las imágenes se reproducen casi al instante, por lo que la paralelización fue un éxito. La desventaja es que no puedo hacer que los fragmentos individuales dependan de la salida de cualquier otro fragmento, por lo que no hay forma de obtener el aumento de calidad significativo que puede obtener al no elegir el mismo mosaico dos veces dentro de un cierto rango. Entonces, resultados rápidos, pero calidad limitada debido a repeticiones masivas de mosaicos. En general, fue divertido. http://imgur.com/a/M0Db0 para versiones de tamaño completo.
fuente
Pitón
Aquí va la primera solución de Python, utilizando un enfoque medio. Podemos evolucionar desde aquí. El resto de las imágenes están aquí .
fuente
Otra solución más de Python: basada en el promedio (RGB vs L a b *)
Resultados (hay algunas diferencias ligeramente)
Bombilla - RGB
vista completa
Bombilla - Laboratorio
vista completa
Steve - RGB
vista completa
Steve - Laboratorio
vista completa
Esferas - RGB
vista completa
Esferas - Laboratorio
vista completa
Domingo - RGB
vista completa
Domingo - laboratorio
vista completa
Beso - RGB
vista completa
Beso - laboratorio
vista completa
Código
requiere python-colormath para Lab
fuente