¿Cuántas formas hay en esta imagen?

10

Los niños son muy buenos para clasificar objetos y contarlos. Las computadoras parecen tener más problemas. Esta es una versión simplificada de este problema. ¿Puedes escribir un pequeño programa que pueda clasificar y contar objetos en una imagen?

El problema: dada una imagen que contiene uno o más círculos y rectángulos, devuelve 2 enteros con el recuento de círculos y el recuento de rectángulos.

Reglas

  • La imagen de entrada será figuras negras sobre un fondo blanco en cualquier formato de mapa de bits que elija.
  • El ancho y la altura de la imagen estarán entre 100 y 1000 píxeles.
  • Las figuras estarán completamente contenidas dentro de la imagen.
  • Las figuras tendrán un ancho de línea de 1 píxel.
  • Las imágenes no usarán anti-aliasing. Serán negros sobre blanco solamente.
  • Las figuras pueden tocarse, cruzarse o estar dentro de otra figura.
  • Las figuras que se cruzan tendrán un máximo de 4 píxeles comunes.
  • Los círculos tendrán un diámetro de 20 píxeles o más.
  • Los lados del rectángulo tendrán 10 o más píxeles de largo.
  • No puede utilizar ninguna biblioteca integrada o biblioteca que reconozca formas, ni ninguna otra función que haga que este desafío sea trivial.
  • Devuelve o imprime 2 enteros con los recuentos de círculos y rectángulos.

Ejemplo 1

Ejemplo 1

Respuesta: 3 4

Ejemplo 2

ingrese la descripción de la imagen aquí

Respuesta: 4 13

Este es un desafío de código de golf, por lo que ganará el programa o la función más corta en cada idioma.

Caballero Lógico
fuente
Ya puedo decir que contar el rectángulo se trata de contar esquinas, aunque los círculos serán mucho más difíciles.
Bálint

Respuestas:

3

PHP - 355 bytes

El recuento de bytes no incluye '<image-url>'.

<?php
m('<image-url>');function m($f){$i=imagecreatefrompng($f);$r=f($i,17);$c=f($i,9);echo($c-$r).' '.$r."\n";}function f($i,$k){$w=imagesx($i);$h=imagesy($i);$r=0;for($y=0;$y<$h;$y++)for($x=0;$x<$w;$x++)if(!imagecolorat($i,$x,$y))$r+=g($i,$x,$y,$w,$k);return$r;}function g($i,&$x,$y,$w,$k){$l=$x;while(!imagecolorat($i,$x,$y)&&$x<$w)$x++;return($x-$l>$k)?1/2:0;}

En los dos casos de prueba, las URL que utilicé son http://i.stack.imgur.com/qnIFk.png y http://i.stack.imgur.com/HV9k3.png.

Cuenta las líneas horizontales y las divide entre dos para obtener el número de formas. Se basa en la observación de que los círculos tienen segmentos horizontales más cortos y los rectángulos tienen segmentos horizontales más largos.

Hack admitido, ¡no se garantiza que funcione para nada más que los casos de prueba!

Intenté rotar las imágenes en ± 45 ° y detectar líneas horizontales. Esto sería equivalente a verificar las líneas diagonales y recogería mejor los círculos, pero no pude encontrar un algoritmo de interpolación que dejara suficientes bordes limpios para trabajar. Por ejemplo, pueden difuminar una línea en dos filas de píxeles y desordenar el recuento.


fuente