MS Paint siempre fue un gran desperdicio de tiempo, pero fue rechazado por la mayoría de los diseñadores gráficos. Tal vez las personas perdieron interés debido a la paleta de colores discordantes, o debido a los niveles limitados de deshacer. De todos modos, todavía es posible generar bellas imágenes con solo el pincel estándar y la paleta de colores predeterminada.
Desafío
Usando solo el pincel predeterminado (un cuadrado de 4x4 sin esquinas) y la paleta de colores predeterminada (los 28 colores a continuación), intente replicar una imagen fuente usando una técnica basada en la escalada estocástica de la colina .
Algoritmo
Cada respuesta debe seguir el mismo algoritmo básico (hillclimb estocástico). Los detalles se pueden ajustar dentro de cada paso. Un movimiento se considera un trazo del pincel (es decir, hacer clic en la pintura).
- Adivina los próximos movimientos. Haga una conjetura (de coordenadas y colores) para los próximos movimientos como desee. Sin embargo, la suposición no debe hacer referencia a la imagen de origen.
- Aplica la suposición. Aplique el pincel a la pintura para hacer los movimientos.
- Mida el beneficio de los movimientos. Al hacer referencia a la imagen de origen, determine si los movimientos beneficiaron a la pintura (es decir, la pintura se parece más a la imagen de origen). Si es beneficioso, mantenga los movimientos, de lo contrario descarte los movimientos.
- Repita hasta la convergencia. Vaya al Paso 1 e intente la siguiente suposición hasta que el algoritmo haya convergido lo suficiente. La pintura debe parecerse mucho a la imagen de origen en este punto.
Si su programa no coincide con estos cuatro pasos, probablemente no sea un hillclimb estocástico. He etiquetado esto como un concurso de popularidad porque el objetivo es producir algoritmos de pintura interesantes basados en la paleta de colores y el pincel limitados.
Contracciones
- El algoritmo debe ser estocástico de alguna manera.
La siguiente suposición no debe verse influenciada por la imagen de origen. Está adivinando cada movimiento nuevo y luego verificando si ayudó o no. Por ejemplo, no está permitido determinar dónde colocar el pincel en función de los colores de la imagen de origen (que es similar al tramado de la imagen de origen, que no es el objetivo).
Puede influir en la ubicación ajustando los pasos del algoritmo como desee. Por ejemplo, podría comenzar sus conjeturas en los bordes y moverse hacia adentro, arrastrar el pincel para crear líneas para cada conjetura o decidir pintar primero colores oscuros. Se le permite hacer referencia a imágenes de iteración anteriores (pero no a la imagen de origen) para calcular el siguiente movimiento deseado. Estos pueden ser restrictivos como desee (es decir, solo hacer conjeturas dentro del cuadrante superior izquierdo para la iteración actual).
La medida de la "diferencia" entre la imagen de origen y la iteración actual se puede medir de la manera que desee, siempre que no calcule otros movimientos potenciales para determinar si este movimiento se considera el "mejor". No debe saber si el movimiento actual es el "mejor", solo si se ajusta a la tolerancia de los criterios de aceptación. Por ejemplo, puede ser tan simple como
abs(src.R - current.R) + abs(src.G - current.G) + abs(src.B - current.B)
para cada píxel afectado, o cualquiera de las técnicas conocidas de diferencia de color .
Paleta
Puede descargar la paleta como una imagen de 28x1 o crearla directamente en el código.
Cepillo
El pincel es un cuadrado de 4x4 sin esquinas. Esta es una versión a escala del mismo:
(Su código debe usar la versión 4x4)
Ejemplo
Entrada:
Salida:
Puede ver cómo progresa el algoritmo básico en un video corto que hice (cada cuadro es de 500 iteraciones): La noche estrellada . Las etapas iniciales son interesantes de ver:
fuente
Respuestas:
JavaScript
Esta solución usa el elemento de lienzo HTML5 para extraer los datos de la imagen, pero sin la necesidad de usar HTML, eso significa que puede ejecutarse en su consola. Accede a la imagen de la paleta de colores como una matriz; Almacené todos los colores de la imagen de la paleta en una matriz). Sale a la consola (después de que termina) y también almacena el resultado en una variable.
La versión más actualizada del código está en el violín . El violín también utiliza un mejor algoritmo para reducir el ruido en las imágenes. La mejora en el algoritmo es principalmente la fijación de una función (máximo a mínimo) que hizo que se eligiera el color inverso.
¡Código con la forma del icono de MS Paint! (código formateado en violín o fragmento de pila)
Uso:
Violín .
El violín utiliza crossorigin.me para que no tenga que preocuparse por el intercambio de recursos de origen cruzado.
También he actualizado el violín para que pueda ajustar algunos valores para producir la pintura más atractiva. Los colores de algunas imágenes pueden estar apagados, para evitar esto, ajuste la tasa de aceptación para ajustar el algoritmo. Un número más bajo significa mejores gradientes, un número más alto dará como resultado colores más nítidos.
Aquí está el violín como un fragmento de pila (NO actualizado, en caso de que el violín no funcione):
Mostrar fragmento de código
Para conmemorar el sobrevuelo de Plutón de New Horizon, ingresé una imagen de Plutón:
Para lo siguiente, lo configuré para que se parezcan al original lo más cerca posible:
Ejecuté esto con el fondo de pantalla predeterminado de OS X Yosemite. Después de dejarlo correr un poco, los resultados son absolutamente impresionantes. El archivo original era enorme (26 MB), así que lo redimensioné y lo comprimí:
La noche estrellada (he usado una imagen de mayor resolución para obtener mejores resultados)
Una imagen que encontré en google:
fuente
JavaScript + HTML
Aleatorio:
Punto aleatorio
Alineado al azar:
Subdivide el lienzo en cuadrados de 4x4 y elige un punto al azar dentro de uno de los cuadrados. Los desplazamientos moverán la cuadrícula, por lo que puede completar los pequeños espacios.
Lazo:
Crea una cuadrícula y recorre todos los puntos. Offsets mueve la cuadrícula. El espaciado determina el tamaño de cada celda. (Comenzarán a superponerse)
Diferencia de color:
RGB:
HSL:
HSV:
fuente
document.cookie
(después de 1000 iteraciones) porque el documento está protegido. ¿Es necesaria la cookie?doThing
lugar deloop
. Es posible que el aumento de velocidad valga la línea extra ...C # (implementación de referencia)
Este es el código utilizado para generar las imágenes en la pregunta. Pensé que sería útil darles a algunas personas una referencia para organizar su algoritmo. Se selecciona una coordenada y un color completamente al azar en cada movimiento. Funciona sorprendentemente bien teniendo en cuenta las limitaciones impuestas por los criterios de aceptación / tamaño del pincel.
Utilizo el algoritmo CIEDE2000 para medir las diferencias de color, de la biblioteca de código abierto ColorMine . Esto debería dar coincidencias de color más cercanas (desde una perspectiva humana), pero no parece ser una diferencia notable cuando se usa con esta paleta.
Luego, puede generar series de imágenes (como mi video) llamando a una instancia de forma similar al código siguiente (ajuste en función del número de iteraciones / fotogramas / nombre deseado). El primer argumento es la ruta del archivo a la imagen de origen, el segundo argumento es la ruta del archivo a la paleta (vinculada en la pregunta), y el tercer argumento es la ruta del archivo para las imágenes de salida.
Busqué algunas pinturas de lienzo coloridas en línea y encontré las imágenes a continuación, que parecen ser excelentes (complicadas) imágenes de prueba. Todos los derechos de autor pertenecen a sus respectivos dueños.
Fuente
Fuente
Fuente
fuente
JavaScript Canvas
Actualizar
Excelentes sugerencias en los comentarios. ¡Ahora es más rápido y no ralentiza la interfaz de usuario!
fuente
Mathematica
Sin embargo, no es realmente tan rápido, pero al menos produce imágenes vagamente reconocibles, así que estoy feliz.
Salida:
La salida probablemente podría ser un poco mejor con más iteraciones, y todavía hay muchas cosas que puedo tratar de acelerar / mejorar la convergencia, pero por ahora esto parece lo suficientemente bueno.
fuente
SmileBASIC
Imagen MSPAINT % [] , ancho% , altura% , pasos% SALIDA % []
fuente