He estado jugando a hacer mosaicos de imágenes. Mi script toma una gran cantidad de imágenes, las reduce a un tamaño de miniatura y luego las usa como mosaicos para aproximar una imagen de destino.
El enfoque es realmente bastante agradable:
Calculo el error cuadrático medio para cada pulgar en cada posición de mosaico.
Al principio, solo usé una ubicación codiciosa: coloque el pulgar con el menor error en el mosaico que mejor se ajuste, y luego el siguiente y así sucesivamente.
El problema con codicioso es que eventualmente te deja colocando los pulgares más diferentes en las fichas menos populares, ya sea que coincidan o no. Muestro ejemplos aquí: http://williamedwardscoder.tumblr.com/post/84505278488/making-image-mosaics
Entonces hago intercambios aleatorios hasta que el script se interrumpe. Los resultados están bastante bien.
Un intercambio aleatorio de dos mosaicos no siempre es una mejora, pero a veces una rotación de tres o más mosaicos da como resultado una mejora global, es decir, A <-> B
puede no mejorar, pero A -> B -> C -> A
1
puede ...
Por esta razón, después de elegir dos fichas aleatorias y descubrir que no mejoran, elijo un montón de fichas para evaluar si pueden ser la tercera ficha en esa rotación. No exploro si cualquier conjunto de cuatro mosaicos se puede rotar de manera rentable, y así sucesivamente; eso sería súper costoso muy pronto.
Pero esto lleva tiempo. ¡Mucho tiempo!
¿Existe un enfoque mejor y más rápido?
Bounty Update
Probé varias implementaciones de Python y enlaces del método húngaro .
Por mucho, el más rápido fue el Python puro https://github.com/xtof-durr/makeSimple/blob/master/Munkres/kuhnMunkres.py
Mi presentimiento es que esto se aproxima a la respuesta óptima; cuando se ejecuta en una imagen de prueba, todas las demás bibliotecas estuvieron de acuerdo con el resultado, pero este kuhnMunkres.py, aunque fue mucho más rápido, solo se acercó mucho al puntaje que acordaron las otras implementaciones.
La velocidad depende mucho de los datos; Mona Lisa se apresuró a través de kuhnMunkres.py en 13 minutos, pero el Perico Escarlata Escarlata tardó 16 minutos.
Los resultados fueron muy similares a los intercambios y rotaciones aleatorias para el periquito:
(kuhnMunkres.py a la izquierda, intercambios aleatorios a la derecha; imagen original para comparar )
Sin embargo, para la imagen de Mona Lisa con la que probé, los resultados mejoraron notablemente y en realidad hizo que su 'sonrisa' definida brillara:
(kuhnMunkres.py a la izquierda, intercambios aleatorios a la derecha)
fuente
Respuestas:
Sí, hay dos enfoques mejores y más rápidos.
Luego, puede ajustar sus costos reemplazando MSE por una distancia visualmente más precisa, sin cambiar el algoritmo subyacente.
fuente
Estoy razonablemente seguro de que es un problema NP-difícil. Para encontrar una solución 'perfecta', debe probar todas las posibilidades exhaustivamente, y eso es exponencial.
Un enfoque sería utilizar el ajuste codicioso y luego tratar de mejorarlo. Eso podría ser tomando una imagen mal colocada (una de las últimas) y encontrando otro lugar para colocarla, luego tomando esa imagen y moviéndola y así sucesivamente. Ha terminado cuando (a) se le acaba el tiempo (b) el ajuste es "suficientemente bueno".
Si introduce un elemento probabilístico, podría dar lugar a un enfoque de recocido simulado o un algoritmo genético. Quizás todo lo que está tratando de lograr es difundir los errores de manera uniforme. Sospecho que esto se está acercando a lo que ya está haciendo, por lo que la respuesta es: con el algoritmo correcto, puede obtener un mejor resultado más rápido, pero no hay un atajo mágico para Nirvana.
Sí, esto es similar a lo que ya estás haciendo. El punto es olvidar una respuesta mágica y pensar en términos de 2 algoritmos: primero rellenar, luego optimizar.
El relleno podría ser: aleatorio, mejor disponible, primero mejor, lo suficientemente bueno, algún tipo de punto caliente.
La optimización podría ser aleatoria, corregir lo peor o (como sugerí) un recocido simulado o un algoritmo genético.
Necesita una métrica de 'bondad' y una cantidad de tiempo que esté preparado para gastar en ella y simplemente experimentar. O encuentre a alguien que realmente lo haya hecho.
fuente
Si los últimos mosaicos son su problema, debe intentar colocarlos desde el principio, de alguna manera;)
Un enfoque sería mirar el mosaico que está más alejado del x% superior de sus coincidencias (intuitivamente iría con 33%) y colocarlo en su mejor coincidencia. Esa es la mejor combinación que puede obtener de todos modos.
Además, puede optar por no utilizar la mejor coincidencia para la peor ficha, sino aquella en la que introduce el menor error en comparación con la mejor coincidencia para esa ranura, de modo que no descarte por completo sus mejores coincidencias por el simple hecho de " control de daños".
Otra cosa a tener en cuenta es que al final estás produciendo una imagen para que sea procesada por un ojo. Entonces, lo que realmente desea es utilizar un poco de detección de bordes para determinar qué posiciones en su imagen son más importantes. Del mismo modo, lo que sucede en la periferia de la imagen tiene poco valor para la calidad del efecto. Superponga estos dos pesos e inclúyalos en su cálculo de distancia. Cualquier inquietud que obtenga debe gravitar hacia el borde y lejos de los bordes, lo que perturbará mucho menos.
También con la detección de bordes en su lugar, es posible que desee colocar el primer y% con avidez (tal vez hasta que caiga por debajo de un cierto umbral de "nerviosismo" en los mosaicos a la izquierda), de modo que los "puntos calientes" se aborden muy bien, y luego cambie a "control de daños" para el resto.
fuente