Trama una imagen en escala de grises en blanco y negro puro con tu propio algoritmo.
Pautas: debe crear su propio algoritmo nuevo. No puede usar algoritmos preexistentes (ej. Floyd-Steinburg) pero puede usar la técnica general. Su programa debe poder leer una imagen y producir una imagen del mismo tamaño. Este es un concurso de popularidad, por lo que el que produce el mejor (más cercano al original) y el más creativo (determinado por los votos) gana. Bonificación si el código es corto, aunque esto no es necesario.
Puede usar cualquier imagen en escala de grises que desee como entrada, debe ser mayor que 300x300. Cualquier formato de archivo está bien.
Entrada de ejemplo:
Salida de ejemplo:
Este es un trabajo bastante bueno, pero todavía hay líneas y patrones visibles.
Respuestas:
Fortran
De acuerdo, estoy usando un formato de imagen oscuro llamado FITS que se usa para astronomía. Esto significa que hay una biblioteca Fortran para leer y escribir tales imágenes. Además, ImageMagick y Gimp pueden leer / escribir imágenes FITS.
El algoritmo que uso se basa en el tramado "Sierra Lite", pero con dos mejoras:
a) Reduzco el error propagado en un factor 4/5.
b) Introduzco una variación aleatoria en la matriz de difusión mientras mantengo su suma constante.
Juntos, estos eluyen casi por completo los patrones vistos en el ejemplo de OP.
Suponiendo que tiene instalada la biblioteca CFITSIO, compile con
Los nombres de los archivos están codificados (no se pudo molestar en arreglar esto).
Código:
Ejemplo de salida para la imagen del cachorro en OPs post:
OPs ejemplo de salida:
fuente
GraphicsMagick / ImageMagick
Dither ordenado:
Antes de quejarse de que use un "algoritmo establecido", lea el ChangeLog para GraphicsMagick e ImageMagick de abril de 2003, donde verá que implementé el algoritmo en esas aplicaciones. Además, la combinación de "-gamma .45455" con "-order-dither" es nueva.
El "-gamma .45455" se encarga de que la imagen sea demasiado clara. El parámetro "todos" solo es necesario con GraphicsMagick.
Hay bandas porque solo hay 17 niveles de grayle en una imagen de tramado ordenado de 4x4. La aparición de bandas puede reducirse mediante el uso de un tramado ordenado de 8x8 que tiene 65 niveles.
Aquí están la imagen original, la salida diferida ordenada 4x4 y 8x8 y la salida de umbral aleatorio:
Prefiero la versión de tramado ordenado, pero incluyo la versión de umbral aleatorio para completar.
El "10x90%" significa hacer que los píxeles de intensidad por debajo del 10 por ciento sean de color negro puro y por encima del 90 por ciento de color blanco puro, para evitar tener algunas manchas solitarias en esas áreas.
Probablemente valga la pena señalar que ambos son tan eficientes en cuanto a memoria como pueden ser. Tampoco difunde, por lo que trabajan un píxel a la vez, incluso cuando se escriben bloques ordenados de interpolación, y no necesitan saber nada sobre los píxeles vecinos. ImageMagick y GraphicsMagick procesan una fila a la vez, pero no es necesario para estos métodos. Las conversiones de tramado ordenado toman menos de .04 segundos en tiempo real en mi vieja computadora x86_64.
fuente
Pido disculpas por el estilo de código, intente esto usando algunas bibliotecas que acabamos de construir en mi clase de Java, y tiene un mal caso de copiar y pegar números mágicos. El algoritmo selecciona rectángulos aleatorios en la imagen y verifica si el brillo promedio es mayor en la imagen difuminada o en la imagen original. Luego activa o desactiva un píxel para acercar los brillos en línea, eligiendo preferentemente los píxeles que son más diferentes de la imagen original. Creo que hace un mejor trabajo al resaltar detalles finos como el pelo del cachorro, pero la imagen es más ruidosa porque trata de resaltar detalles incluso en áreas sin ninguno.
fuente
Ghostscript (con poca ayuda de ImageMagick)
Lejos de ser mi 'nuevo algoritmo', pero, lo siento, no pude resistirlo.
Por supuesto, funciona mejor sin restricciones del 'mismo tamaño'.
fuente
JAVA
Aquí está mi presentación. Toma una imagen JPG, calcula la luminosidad de píxel por píxel (gracias a Bonan en esta pregunta SO) y luego la compara con un patrón aleatorio para saber si el píxel resultante será blanco o negro. Los píxeles más oscuros siempre serán negros y los píxeles más brillantes siempre serán blancos para preservar los detalles de la imagen.
Otros ejemplos:
También funciona con imágenes a todo color:
fuente
CJam
95 bytes :)
Utiliza el formato ASCII PGM (P2) sin línea de comentario, tanto para entrada como para salida.
El método es muy básico: suma cuadrados de 2 * 2 píxeles, los convierte al rango 0..4, luego usa un patrón correspondiente de 4 bits para generar 2 * 2 píxeles en blanco y negro.
Eso también significa que el ancho y la altura deben ser uniformes.
Muestra:
Y un algoritmo aleatorio en solo 27 bytes:
Utiliza el mismo formato de archivo.
Muestra:
Y finalmente un enfoque mixto: tramado aleatorio con un sesgo hacia un patrón de tablero de ajedrez; 44 bytes:
Muestra:
fuente
Java (1.4+)
No estoy seguro de si estoy reinventando la rueda aquí, pero creo que puede ser única ...
Con secuencias aleatorias limitadas
Dithering puro al azar
Imagen de la ciudad de la respuesta de Averroes
El algoritmo utiliza el concepto de energía de luminosidad localizada y normalización para retener características. La versión inicial luego usó un jitter aleatorio para producir un aspecto difuso sobre áreas de luminosidad similar. Sin embargo, no era tan visualmente atractivo. Para contrarrestar esto, se asigna un conjunto limitado de secuencias aleatorias limitadas a la luminosidad del píxel de entrada sin procesar y las muestras se usan de forma iterativa y repetida para obtener fondos de aspecto difuso.
fuente
Pitón
La idea es la siguiente: la imagen se divide en
n x n
mosaicos. Calculamos el color promedio de cada uno de esos mosaicos. Luego asignamos el rango de color0 - 255
al rango0 - n*n
que nos da un nuevo valorv
. Luego coloreamos todos los píxeles de ese mosaico en negro, y coloreamos al azar losv
píxeles dentro de ese mosaico en blanco. Está lejos de ser óptimo, pero aún nos da resultados reconocibles. Dependiendo de la resolución, generalmente funciona mejor enn=2
on=3
. Si bienn=2
ya puede encontrar artefactos de la 'profundidad de color simulada, en caso den=3
que ya pueda ponerse algo borrosa. Supuse que las imágenes deberían permanecer del mismo tamaño, pero por supuesto, también puede usar este método y simplemente duplicar / triplicar el tamaño de la imagen generada para obtener más detalles.PD: Sé que llego un poco tarde a la fiesta, recuerdo que no tenía ninguna idea cuando comenzó el desafío, pero ahora solo tenía esta onda cerebral =)
Resultados:
n=2:
n=3:
fuente
Definamos un formato de archivo teórico muy compacto para esta pregunta, ya que cualquiera de los formatos de archivo existentes tiene demasiada sobrecarga para escribir una respuesta rápida.
Deje que los primeros cuatro bytes del archivo de imagen definan el ancho y el alto de la imagen en píxeles, respectivamente:
seguido de
w * h
bytes de valores de escala de grises de 0 a 255:Luego, podemos definir un fragmento de código en Python (145 bytes) que tomará esta imagen y hará:
que "se tambalea" al devolver blanco o negro con una probabilidad igual al valor de escala de grises de ese píxel.
Aplicado en la imagen de muestra, da algo como esto:
No es demasiado bonito, pero se ve muy similar cuando se reduce en una vista previa, y por solo 145 bytes de Python, no creo que pueda mejorar mucho.
fuente
Cobra
Toma un archivo PNG / BMP de 24 o 32 bits (JPG produce una salida con algunos grises). También es extensible a archivos que contienen color.
Utiliza ELA de velocidad optimizada para oscurecer la imagen en color de 3 bits, que volverá a ser blanco / negro cuando se le dé su imagen de prueba.
¿Mencioné que es realmente rápido?
fuente
col
y dejarlaimage.setPixel(x,y,col)
hasta el final?Java
Código de bajo nivel, usando PNGJ y una adición de ruido más difusión básica. Esta implementación requiere una fuente PNG de 8 bits en escala de grises.
(Agregue este jar a su ruta de compilación si desea probarlo).
Como beneficio adicional: esto es extremadamente eficiente en el uso de memoria (solo almacena tres filas), por lo que podría usarse para imágenes enormes.
fuente
Java
Solo un algoritmo simple basado en RNG, más algo de lógica para manejar imágenes en color. Tiene probabilidad b de establecer cualquier píxel dado en blanco, de lo contrario lo establece en negro; donde b es el brillo original de ese píxel.
Aquí hay un resultado potencial para la imagen del perro:
fuente