Usando Algodoo y Paint hice estas seis imágenes monocromáticas de 300 × 300 de cuatro formas convenientes:
Esta clase de imágenes tiene las siguientes propiedades:
- Siempre son 300 × 300 píxeles, monocromáticos (solo en blanco y negro), y tienen exactamente cuatro regiones blancas que corresponden a un cuadrado, un círculo, un triángulo y un engranaje.
- Las formas nunca se superponen o se tocan entre sí, ni tocan el borde de la imagen ni se salen de los límites.
- Las formas siempre tienen el mismo tamaño, pero pueden rotarse y colocarse de cualquier manera.
(Las formas también tienen áreas iguales, aunque cuando se trazan así, es poco probable que sus recuentos de píxeles sean exactamente equivalentes).
Desafío
Escriba el programa o función más breve posible que tome el nombre de archivo de dicha imagen y convierta todos los píxeles blancos ...
- rojo
(255, 0, 0)
si están en la plaza. - azul
(0, 0, 255)
si están en el círculo. - verde
(0, 255, 0)
si están en el triángulo. - amarillo
(255, 255, 0)
si están en la marcha.
p.ej
Detalles
Su programa debería funcionar para todas las imágenes de entrada posibles. (Solo se ingresarán imágenes monocromáticas válidas de 300 × 300). Las seis imágenes que he proporcionado son meramente ejemplos, no puede codificar su salida en su programa.
No puede utilizar bibliotecas o funciones de visión artificial, integradas o externas. El punto es hacer esto usando sus propias operaciones a nivel de píxel. Puede usar bibliotecas de imágenes que simplemente le permiten abrir y modificar imágenes (por ejemplo, PIL para Python).
Puede utilizar cualquier formato de archivo de imagen sin pérdida común para entrada y salida, siempre y cuando se adhiera al esquema de color.
Puede tomar el nombre de archivo de la imagen como argumento de función, desde stdin o desde la línea de comando. La imagen de salida puede guardarse en un nuevo archivo, el mismo archivo, o simplemente mostrarse.
Puntuación
El envío con la menor cantidad de bytes gana. Puedo probar los envíos con imágenes adicionales para determinar su validez.
fuente
Respuestas:
J -
246,224185 bytes¡Esto fue divertido!
Reutilicé la parte de componentes conectados que usé para el desafío "Estoy en la habitación más grande" , y usé la relación entre la distancia promedio y máxima de todos los puntos al centro de cada componente. Me decidí por esto, ya que tanto la escala como la rotación son invariantes, y aparentemente son lo suficientemente buenas como para distinguir entre las formas que se dan. Clasificar este valor de menor a mayor me da el círculo de orden, el engranaje, el cuadrado y el triángulo, utilizados para permutar el mapa de colores.
Muestra el resultado usando el complemento viewmap. No se utilizan cajas de herramientas, excepto para la lectura y salida de archivos.
La robustez no parece ser un requisito, esto quita 18 bytes. 2 espacios innecesarios más, reemplazados
&.>
por&>
inratio
y&.:
por&:
incent para otros 2 bytes.Enorme ganancia en la brevedad y el rendimiento del
comp
uso de cambios en lugar decut
(;.
). De esta forma, la imagen se replica y se desplaza en las 8 direcciones en lugar de escanearla con una ventana de 3x3.La
id
función era ridículamente compleja para lo que tenía que hacer. Ahora asigna las identificaciones a los píxeles en los objetos al multiplicar la imagen con una matriz de números únicos y, por lo tanto, establecer el BG en cero.Código un poco más explicado:
Este es un poco largo para explicar en detalle, pero servirá si hay interés.
fuente
Mathematica,
459392 bytesSin golf:
Podría ahorrar 6 bytes más convirtiéndome
m=1.Mean@a;m=#-m&/@a;
enm=#-Mean@a&/@a;
, pero eso explota significativamente el tiempo de ejecución, lo cual es molesto para las pruebas. (Tenga en cuenta que se trata de dos optimizaciones: extraer el cálculo deMean@a
fuera de bucle y usar tipos simbólicos exactos en lugar de números de punto flotante. Curiosamente, el uso de tipos exactos es mucho más significativo que calcular la media en cada iteración).Entonces este es el enfoque número tres:
Ahora, para todos los píxeles en la forma, tracemos la distancia del ángulo vs al centro:
El triángulo tiene 3 máximos claros, el cuadrado 4, el engranaje 16 y el círculo tiene toneladas, debido a las fluctuaciones de alias sobre el radio constante.
150
es el máximo.Solo para el registro, si uso la idea de Ell, y simplemente clasifico las regiones por la mayor distancia entre cualquier píxel y centro, puedo hacer esto en 342 bytes:
Pero no tengo la intención de competir con eso, siempre y cuando todos los demás estén usando sus propios algoritmos originales, en lugar de jugar golf con los de los demás.
fuente
Java,
1204113210871076Sólo para demostrar a mí mismo que yo puedo hacer esto.
Incluí importaciones justo al lado de las declaraciones de funciones; estos tendrían que estar fuera de la clase para que esto funcione:
Sin golf (y ejecutable; es decir, repetitivo agregado):
Esto funciona iterando sobre cada píxel de la imagen y llenando cada vez que llegamos a un "agujero". Agregamos cada resultado de inundación como
Set<Point>
a aSet
. Luego determinamos qué forma es cuál. Esto se hace mirando el número de píxeles de límite de la forma. Definí el límite como el movimiento de un caballero lejos de un azulejo negro, ya que eso se mantendría más constante entre rotaciones y tal. Cuando hacemos esto, queda claro que las formas se pueden ordenar por ese valor: Círculo, Cuadrado, Triángulo, Engranaje. Así que clasifico y configuro todos los píxeles de esa forma con el color correcto.Tenga en cuenta que la imagen en la que estoy escribiendo no se toma directamente del archivo, porque si tuviera que hacer eso, Java trataría la imagen como blanco y negro y el relleno con colores no funcionaría. Entonces tengo que crear mi propia imagen con
TYPE_INT_RGB
(que es1
). También tenga en cuenta que la imagen en la que estoy trabajando es302
por302
; Esto es para que el algoritmo de distancia del Caballero no tenga que preocuparse por intentar leer fuera de los límites de la imagen. Arreglo esta discrepancia de tamaño llamandoi.getSubImage(1,1,300,300)
. Nota: Puede que haya olvidado arreglar esto cuando cargué las imágenes, en cuyo caso las imágenes tienen 2 píxeles de ancho, pero a excepción de este hecho, deberían ser correctasLa función sobrescribirá el archivo cuya ruta se pasa. Salidas:
fuente
Pitón,
571 567528 bytesDe manera similar a la solución de Quincunx, comienza inundando cada forma con un índice del 1 al 4. Luego determina la identidad de las formas por el radio de su círculo delimitador. Se construye una paleta de colores en consecuencia y la imagen se guarda como una imagen de color indexado.
EDITAR: se perdió el hecho de que se garantiza que las formas no toquen el borde de la imagen. Más corto es, entonces!
Toma un nombre de archivo de entrada en la línea de comando y escribe la salida en
o.png
.fuente
Mathematica 225
Actualización :
El OP decidió que este enfoque utiliza funciones de visión por computadora, por lo que ya no está en funcionamiento. Sin embargo, lo dejaré publicado. Quizás alguien pueda encontrarlo de interés.
ImageData
devuelve la imagen como una matriz de 0 y 1.Flatten
convierte esa matriz en una lista.Morphological Components
encuentra los 4 grupos de píxeles y asigna un número entero distinto, 1, 2, 3, 4 a cada píxel de acuerdo con el grupo. 0 está reservado para el fondo (negro).ComponentMeasurements
prueba la circularidad de los grupos.De mayor a menor circular siempre será: el círculo, el cuadrado, el triángulo y el engranaje.
ReplacePart
reemplaza cada número entero componente con el color RGB respectivo, usando la clasificación de circularidad.Partition...Dimensions[m][[2]]
toma la lista de colores de píxeles y devuelve una matriz de las mismas dimensiones que la imagen de entrada.Image
Convierte la matriz de colores de píxeles en una imagen coloreada.fuente
f@i_:=Image[#/.Append[Thread[Ordering[Last/@ComponentMeasurements[#,"Circularity"]]->{Yellow,Green,Red,Blue}],0->Black]]&@MorphologicalComponents@i
{RGBColor[1, 0, 0], RGBColor[0, 1, 0], RGBColor[0, 0, 1], RGBColor[1, 1, 0]}
1, donde 1 corresponde a 255. No se utilizaron bibliotecas.MorphologicalComponents
satisface o viola sus reglas. Una vez que se sabe a qué grupo pertenece cada píxel, hay muchas formas, incluido un recuento de píxeles sin procesar, para determinar qué figura es cuál.(255,0,22)
cuando verifico en Paint). No tengo Mathematica, así que no puedo correr para asegurarme.Mathematica,
354345314291288Aún jugando al golf, podría acortarse con algunos caracteres más, pero el rendimiento se vuelve insoportable. Utiliza la varianza para identificar formas:
Con espaciado:
Pruebas:
Aquí está completamente sin golf. Agregará explicaciones más tarde:
fuente
Python,
579577554514502501 bytesPara cada forma, la inundación la llena, luego calcula la distancia entre el centroide y el punto más lejano.
entonces la superficie real de la forma se compara con la superficie de un triángulo, cuadrado, disco o rueda que tendría el mismo tamaño.
fuente
C # 1086 bytes
Sin embargo, otra solución de inundación, solo para el registro ya que no hay una versión de C # aquí. Al igual que Quincunx, quería demostrarme a mí mismo que puedo hacerlo y no hay mucha diferencia en su enfoque en Java.
Acepta cada formato de imagen.
Probablemente se puede quitar algunos caracteres eliminando todas las cosas estáticas y creando una instancia de Programa.
Versión legible:
Golfizado:
fuente