Ver también: análisis
Introducción
Estás trabajando en un equipo de programación del gobierno, que ha estado programando las cámaras de velocidad. Sin embargo, el grupo de personas que ha programado la calculadora de velocidad ha ocupado demasiado espacio, por lo que debe hacer que el software de reconocimiento de matrículas sea lo más pequeño posible.
Desafío
Dada una imagen de una matrícula, devuelva el texto en la placa.
Placas de matrícula
Los siguientes son todos los caracteres que su programa debe reconocer:
ABCDEFG
H1JKLMN0
PQRSTUVW
XYZ01234
56789
Nota
En las matrículas británicas, los caracteres para I (i) y 1 (uno) son los mismos y los caracteres para O (o) y 0 (cero) son los mismos. Por esa razón, siempre asuma que los caracteres son los números. Es decir, la siguiente matrícula es 10 (un cero):
Ejemplos
C0D3 GLF
B3T4 DCY
M1NUS 15
YET1CGN
Otras reglas
El acceso a Internet y las bibliotecas y funciones de OCR están prohibidas.
Las matrículas siempre se verán idénticas a las que se muestran arriba. Todas las matrículas serán aproximadamente del mismo tamaño (habrá algunas imprecisiones debido al método de recorte).
Si necesita versiones PNG sin pérdidas de cualquier número de matrícula, se las proporcionaré.
Puntuación
El programa más corto en bytes gana.
Todas las matrículas son capturas de pantalla de la barra de búsqueda en este sitio
fuente
Respuestas:
C, 409 bytes (y estoy tan sorprendido como cualquiera)
Toma como entrada: el ancho (
w
) y la altura (h
) de la imagen, seguidos de los datos RGB empaquetados como una matriz dechar
s (d
). Todos los demás parámetros de la función son declaraciones de variables disfrazadas. Ignora todo excepto el canal verde y aplica un umbral de 32 como pase inicial.Principalmente igual que el método de @ DavidC, excepto que esto verifica que al menos el 35% de cada cuadro de muestra esté lleno. Esperemos que eso lo haga más robusto para escalar los cambios, pero quién sabe.
Utilicé un método de fuerza bruta para averiguar qué tamaño de muestreo y porcentaje de cobertura utilizar para la mejor confiabilidad (es decir, la menor cantidad de casos de un personaje con múltiples interpretaciones). Resultó que una cuadrícula de 4x5 con una cobertura del 35% era la mejor. Luego utilicé un segundo método de fuerza bruta para calcular la mejor disposición de bits y el valor del módulo para empaquetar los datos de caracteres en una cadena corta: el bit bajo en la parte superior izquierda, que aumenta en x luego y, con el valor final% 101 convertido fuera mejor, dando esta tabla de búsqueda:
Restar 7 significa que las iniciales pueden eliminarse, y las últimas 2 pueden eliminarse sin ningún trabajo adicional. Esta eliminación significa que ciertas entradas inválidas pueden causar una lectura de memoria inválida, por lo que pueden fallar en imágenes particulares.
Uso:
Para obtener las imágenes, escribí un contenedor usando libpng. También resulta que a pesar del nombre del archivo, las imágenes en la pregunta son en realidad jpegs (!), Por lo que primero deberá exportarlas manualmente como png.
Descompostura
fuente
Mathematica
1170 1270 1096 1059 650 528 570 551525498 bytesLa última versión ahorra 27 bytes al no requerir que la placa se "recorte" antes de analizarla. La penúltima versión ahorró 26 bytes al usar solo 10 de los 24 puntos de muestra originales.
122 bytes guardados a través de la idea de LegionMammal978 de empaquetar la larga lista de números de base 10 como un solo número de base 36. Recortó otros 20 bytes del código final.
El salto de 528 a 570 bytes se debió a un código adicional para garantizar que el orden de las letras devueltas correspondiera al orden de las letras en la placa. El centroide de cada letra contiene la coordenada x, que revela las posiciones relativas de las letras a lo largo de x.
Código sin golf
Visión general
La idea básica es verificar si un muestreo sistemático de píxeles de la imagen de entrada coincide con los píxeles de la misma ubicación en las imágenes de buena fe. Gran parte del código consiste en las firmas de bits para cada carácter,
El diagrama muestra los píxeles que se toman de las letras "J", "P", "Q" y "R".
Los valores de píxel se pueden representar como matrices. Los oscuros y en negrita
1
corresponden a las celdas negras. Los0
corresponden a glóbulos blancos.Estas son las reglas de reemplazo de descifrado para JPQ R.
{1, 1, 1, 1, 9, 15} -> "J",
{15, 9, 15, 14, 8, 8} -> "P",
{15, 9, 9, 9, 15, 15 } -> "Q",
{15, 9, 15, 14, 10, 11} -> "R"
Debería ser posible entender por qué la regla para "0" es:
{15, 9, 9, 9, 9, 15} -> "0"
y por lo tanto distinguible de la letra "Q".
A continuación se muestran los 10 puntos utilizados en la versión final. Estos puntos son suficientes para identificar a todos los personajes.
¿Qué hacen las funciones?
plateCrop[img]
elimina el marco y el borde izquierdo de la placa, hace que el fondo sea blanco. Pude eliminar esta función de la versión final seleccionando componentes de imagen, posibles letras que tenían entre 100 y 120 píxeles de alto.isolateLetters[img]
elimina las letras individuales de la imagen recortada.Podemos mostrar cómo funciona mostrando dónde va la imagen recortada, la salida de
plateCrop
como entradaisolateLetters
. La salida es una lista de caracteres individuales.Coordinates
son 24 posiciones distribuidas uniformemente para verificar el color del píxel. Las coordenadas corresponden a las de la primera figura.{{9, 99}, {27, 99}, {45, 99}, {63, 99}, {9, 81}, {27, 81}, {45, 81}, {63, 81}, { 9, 63}, {27, 63}, {45, 63}, {63, 63}, {9, 45}, {27, 45}, {45, 45}, {63, 45}, {9, 27}, {27, 27}, {45, 27}, {63, 27}, {9, 9}, {27, 9}, {45, 9}, {63, 9}}
h
Convierte los píxeles a binario.codes
son la firma de cada personaje. Los valores decimales son abreviaturas del código binario para las celdas negras (0) y blancas (1). En la versión de golf, se utiliza la base 36.(*
decryptRules
son para reemplazar firmas con sus respectivos caracteres *)f
es la función que toma una imagen de una matrícula y devuelve una letra.{"A", "B", "C", "D", "E", "F", "G"}
{"H", "1", "J", "K", "L", "M", "N", "0"}
{"P", "Q", "R", "S", "T", "U", "V", "W"}
{"X", "Y", "Z", "0", "1", "2", "3", "4"}
{"5", "6", "7", "8", "9"}
Golfed
El código se acorta usando un solo número decimal para representar los 24 bits (blanco o negro) para cada carácter. Por ejemplo, la letra "J" utiliza la siguiente regla de sustitución:
1118623 -> "J"
.1118623 corresponde a
{0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1}
que se puede reenvasar como
{{0, 0, 0, 1}, {0, 0, 0, 1}, {0, 0, 0, 1}, {0, 0, 0, 1}, {1, 0, 0, 1} , {1, 1, 1, 1}}
que es simplemente la matriz para "J" que vimos arriba.
Otro ahorro proviene de representar el alfabeto en
"0123456789ABCDEFGHJKLMNPQRSTUVWXYZ"
lugar de una lista de letras.Finalmente, todas las funciones de la versión larga, excepto
h
, se integraron en la función enf
lugar de definirse por separado.fuente
{1118623, 2518818, ..., 16645599}
con esto .x[[All,2,1]]
puede ser reemplazado conx[[;;,2,1]]
.Flatten[x,1]
es equivalente aJoin@@x
, yFlatten[#,1]&/@x
es equivalente aJoin@@@x
. Hay algunas otras optimizaciones menores que se pueden hacer. El código de 551 bytes después de estos campos de golf.C #,
10401027 bytesSin golf:
Básicamente encontré algunos puntos de referencia específicos para verificar amarillo / negro para determinar la identidad de cada personaje.
fuente
csc.exe main.cs /r:System.Drawing.dll
PHP -
174116741143 bytesPrimero se configuró aprendiendo los perfiles de los personajes de los primeros ejemplos, que luego resumieron cada personaje en seis números. Elegí seis porque originalmente tenía cinco, y no funcionó tan bien como me gustaría, pero seis parece funcionar mucho mejor. Gran parte de la optimización implica comprimir estos perfiles en recuentos de bytes cada vez más pequeños.
El primer y segundo perfil
*lhdfdn
y|nnmmkk
son en realidad la mancha azul con "E" en la parte inferior*
y el borde derecho|
, lo que estamos haciendo caso omiso. Es más seguro incluirlos para que la burbuja y el borde derecho tengan algo contra lo que comparar.Debe manejar cualquier formato de imagen, cualquier escala razonable siempre que la relación de aspecto no cambie demasiado, cualquier color oscuro o claro e incluso un poco de ruido y sombreado.
Necesita el borde, al menos en la parte superior e inferior, que es parte del perfil.
Guardar como
ocr.php
, luego ejecutar desde la línea de comando:Para aquellos que estén interesados, aquí está el código de aprendizaje. Guardar como
learn.php
y ejecutar desde la línea de comandos, sin argumentos.fuente
PHP,
971970 bytesSe basa en gran medida en la respuesta de Yimin Rong , que se puede reducir seriamente, especialmente los índices de matriz, y poner en un Phar con compresión gzip.
Descargar el phar
Esta es mi versión base mejorada en
15571535 bytes, guardada simplemente bajo el nombre de archivo "o":Mejoras:
1ra etapa
2da etapa
intval
con~~
(ahorra 8 bytes, dos ocurrencias)file_get_contents($u)
reemplazado conjoin('',file($u))
(ahorra 5 bytes)Desafortunadamente, todas las mejoras de la segunda etapa solo se traducen en 1 byte menos código comprimido. :-RE
Y este código se usó para crear el Phar:
Pruebe con
php ocr.phar http://i.imgur.com/i8jkCJu.png
o con cualquier otra de las imágenes del caso de prueba.fuente