Veja também: Analisando
Introdução
Você está trabalhando em uma equipe de programação do governo, que está programando os radares de velocidade. No entanto, o grupo de pessoas que programou a calculadora de velocidade ocupou muito espaço; portanto, você deve tornar o software de reconhecimento da placa de número o menor possível.
Desafio
Dada a imagem de uma chapa de matrícula, retorne o texto na chapa.
Chapas de matrícula
A seguir, são apresentados todos os caracteres que seu programa deve reconhecer:
ABCDEFG
H1JKLMN0
PQRSTUVW
XYZ01234
56789
Nota
Nas chapas de matrícula britânicas, os caracteres para I (i) e 1 (um) são os mesmos e os caracteres para O (o) e 0 (zero) são os mesmos. Por esse motivo, sempre assuma que os caracteres são os números. Ou seja, a seguinte matrícula é 10 (um zero):
Exemplos
C0D3 GLF
B3T4 DCY
M1NUS 15
YET1CGN
Outras regras
As bibliotecas e funções de acesso à Internet e OCR não são permitidas.
As chapas de matrícula sempre serão idênticas às mostradas acima. Todas as chapas de matrícula terão aproximadamente o mesmo tamanho (haverá algumas imprecisões devido ao método de corte).
Se você precisar de versões PNG sem perdas de quaisquer chapas de matrícula, eu as fornecerei.
Pontuação
O programa mais curto em bytes vence.
Todas as chapas de matrícula são capturas de tela da barra de pesquisa deste site
fonte
Respostas:
C, 409 bytes (e estou tão surpreso quanto qualquer um)
Toma como entrada: a largura (
w
) e a altura (h
) da imagem, seguidas pelos dados RGB compactados como uma matriz dechar
s (d
). Todos os outros parâmetros de função são declarações variáveis disfarçadas. Ignora tudo, exceto o canal verde, e aplica um limite de 32 como um passe inicial.Principalmente o mesmo método do @ DavidC, exceto que isso verifica se pelo menos 35% de cada caixa de amostra está preenchida. Espero que isso torne mais robusto a escala de mudanças, mas quem sabe.
Usei um método de força bruta para descobrir qual tamanho de reamostragem e porcentagem de cobertura usar para obter a melhor confiabilidade (ou seja, o menor número de casos de um personagem com várias interpretações). Verificou-se que uma grade 4x5 com cobertura de 35% era a melhor. Em seguida, usei um segundo método de força bruta para calcular a melhor disposição de bits e valor do módulo para compactar os dados dos caracteres em uma sequência curta - o bit baixo na parte superior esquerda, aumentando em x então y, com o valor final% 101 ativado melhor, fornecendo esta tabela de pesquisa:
Subtrair 7 significa que as iniciais podem ser removidas e as duas últimas podem ser removidas sem nenhum trabalho extra. Essa remoção significa que certas entradas inválidas podem causar uma leitura de memória inválida e, portanto, podem falhar em determinadas imagens.
Uso:
Para colocar as imagens nele, escrevi um wrapper usando libpng. Além disso, apesar do nome do arquivo, as imagens na pergunta são na verdade jpegs (!), Então você precisará exportá-las manualmente como pngs primeiro.
Demolir
fonte
Mathematica
1170 1270 1096 1059 650 528 570 551 525498 bytesA versão mais recente salva 27 bytes ao não exigir que a placa seja "aparada" antes de ser analisada. A penúltima versão salvou 26 bytes usando apenas 10 dos 24 pontos de amostra originais.
122 bytes salvos com a idéia de LegionMammal978 de compactar a longa lista de números da base 10 como um único número da base 36. Ele eliminou outros 20 bytes do código final.
O salto de 528 para 570 bytes ocorreu devido a um código adicional para garantir que a ordem das letras retornadas correspondesse à ordem das letras na placa do carro. O centróide de cada letra contém a coordenada x, que revela as posições relativas das letras ao longo de x.
Código Ungolfed
visão global
A idéia básica é verificar se uma amostragem sistemática de pixels da imagem de entrada corresponde a pixels do mesmo local nas imagens de boa-fé. Grande parte do código consiste em assinaturas de bit para cada caractere,
O diagrama mostra os pixels que são amostrados das letras "J", "P", "Q" e "R".
Os valores de pixel podem ser representados como matrizes. O escuro, negrito
1
corresponde a células pretas. Os0
correspondem a glóbulos brancos.Estas são as regras de substituição de descriptografia 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"
Deve ser possível entender por que a regra para "0" é:
{15, 9, 9, 9, 9, 15} -> "0"
e, portanto, distinguível da letra "Q".
A seguir, são mostrados os 10 pontos usados na versão final. Esses pontos são suficientes para identificar todos os caracteres.
O que as funções fazem
plateCrop[img]
remove o quadro e a borda esquerda da placa, deixa o fundo branco. Consegui eliminar essa função da versão final selecionando componentes de imagem, possíveis letras com altura entre 100 e 120 pixels.isolateLetters[img]
remove as letras individuais da imagem cortada.Podemos mostrar como funciona, mostrando para onde a imagem cortada e a saída
plateCrop
são inseridasisolateLetters
. A saída é uma lista de caracteres individuais.Coordinates
são 24 posições uniformemente distribuídas para verificar a cor do pixel. As coordenadas correspondem às da primeira 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
converte os pixels em binários.codes
são a assinatura de cada personagem. Os valores decimais são abreviações do código binário para células pretas (0) e brancas (1). Na versão de golfe, a base 36 é usada.(*
decryptRules
são para substituir assinaturas por seus respectivos caracteres *)f
é a função que tira uma imagem de uma placa e retorna uma carta.{"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"}
Golfe
O código é reduzido usando um único número decimal para representar todos os 24 bits (branco ou preto) para cada caractere. Por exemplo, a letra "J" usa a seguinte regra de substituição:
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 pode ser reembalado 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 é simplesmente a matriz para "J" que vimos acima.
Outra economia vem da representação do alfabeto
"0123456789ABCDEFGHJKLMNPQRSTUVWXYZ"
e não da lista de letras.Por fim, todas as funções da versão longa, exceto
h
, foram integradas à função emf
vez de definidas separadamente.fonte
{1118623, 2518818, ..., 16645599}
por isso .x[[All,2,1]]
pode ser substituído porx[[;;,2,1]]
.Flatten[x,1]
é equivalente aJoin@@x
eFlatten[#,1]&/@x
é equivalente aJoin@@@x
. Existem algumas outras otimizações menores que podem ser feitas. O código de 551 bytes depois desses campos de golfe.C #,
10401027 bytesUngolfed:
Basicamente, encontrei alguns pontos de referência específicos para verificar amarelo / preto para determinar a identidade de cada personagem.
fonte
csc.exe main.cs /r:System.Drawing.dll
PHP -
174116741143 bytesFoi criado pela primeira vez, aprendendo os perfis dos personagens nos primeiros exemplos, que resumiram cada caractere em seis números. Escolhi seis porque originalmente tinha cinco, e não funcionou tão bem quanto eu gostaria, mas seis parece funcionar muito melhor. Grande parte da otimização envolve a compressão desses perfis em contagens de bytes cada vez menores.
O primeiro e o segundo perfil
*lhdfdn
e|nnmmkk
são na verdade o blob azul com "GB" na parte inferior*
e a borda direita|
, que estamos ignorando. É mais seguro incluí-los para que o blob e a borda direita tenham algo a que corresponder.Deve lidar com qualquer formato de imagem, qualquer escala razoável, desde que a proporção não mude muito, qualquer cor escura ou clara e até um pouco de ruído e sombreamento!
Ele precisa da borda, pelo menos na parte superior e inferior, que faz parte do perfil.
Salve como
ocr.php
e execute a partir da linha de comando:Para aqueles que estão interessados, aqui está o código de aprendizado. Salve como
learn.php
e execute na linha de comando, sem argumentos.fonte
PHP,
971970 bytesInspira-se fortemente sobre Yimin Rong 's resposta , que pode ser seriamente golfed para baixo, especialmente os índices de array, e colocados em um Phar com compressão gzip.
Faça o download do phar
Esta é minha versão base aprimorada em
15571535 bytes, salva simplesmente sob o nome de arquivo "o":Melhorias:
1ª etapa
2ª etapa
intval
por~~
(salva 8 bytes, duas ocorrências)file_get_contents($u)
substituído porjoin('',file($u))
(salva 5 bytes)Infelizmente, todas as melhorias no segundo estágio são convertidas apenas em um código com menos bytes compactados em gzip. :-D
E esse código foi usado para criar o Phar:
Teste com
php ocr.phar http://i.imgur.com/i8jkCJu.png
ou qualquer outra imagem de caso de teste.fonte