Voir aussi: Analyse
introduction
Vous travaillez sur une équipe de programmation gouvernementale qui a programmé les radars. Cependant, le groupe de personnes qui a programmé le calculateur de vitesse a pris trop de place, vous devez donc rendre le logiciel de reconnaissance de plaque d'immatriculation aussi petit que possible.
Défi
Étant donné l'image d'une plaque d'immatriculation, renvoyez le texte sur la plaque.
Plaques d'immatriculation
Voici tous les caractères que votre programme doit reconnaître:
ABCDEFG
H1JKLMN0
PQRSTUVW
XYZ01234
56789
Remarque
Sur les plaques d'immatriculation britanniques, les caractères pour I (i) et 1 (un) sont les mêmes et les caractères pour O (o) et 0 (zéro) sont les mêmes. Pour cette raison, supposez toujours que les caractères sont les nombres. Autrement dit, la plaque d'immatriculation suivante est 10 (un zéro):
Exemples
C0D3 GLF
B3T4 DCY
M1NUS 15
YET1CGN
Autres règles
L'accès à Internet et les bibliothèques et fonctions OCR sont interdits.
Les plaques d'immatriculation seront toujours identiques à celles illustrées ci-dessus. Toutes les plaques d'immatriculation seront à peu près de la même taille (il y aura des inexactitudes dues à la méthode de recadrage).
Si vous avez besoin de versions PNG sans perte de toutes les plaques d'immatriculation, je vous les fournirai.
Notation
Le programme le plus court en octets gagne.
Toutes les plaques d'immatriculation sont des captures d'écran de la barre de recherche de ce site
Réponses:
C, 409 octets (et je suis aussi surpris que quiconque)
Prend en entrée: la largeur (
w
) et la hauteur (h
) de l'image, suivies des données RVB compressées sous la forme d'un tableau dechar
s (d
). Tous les autres paramètres de fonction sont des déclarations de variables déguisées. Ignore tout sauf le canal vert et applique un seuil de 32 comme passe initiale.Généralement identique à la méthode de @ DavidC, sauf que cela vérifie qu'au moins 35% de chaque boîte d'échantillon est remplie. Espérons que cela rendra les changements d'échelle plus robustes, mais qui sait.
J'ai utilisé une méthode de force brute pour déterminer la taille de rééchantillonnage et le pourcentage de couverture à utiliser pour la meilleure fiabilité (c'est-à-dire le moins de cas d'un caractère ayant plusieurs interprétations). Il s'est avéré qu'une grille 4x5 avec une couverture de 35% était la meilleure. J'ai ensuite utilisé une deuxième méthode de force brute pour calculer la meilleure disposition des bits et la meilleure valeur modulo pour regrouper les données de caractères dans une courte chaîne - le bit bas en haut à gauche, augmentant en x puis y, avec la valeur finale% 101 tournée mieux, donnant cette table de correspondance:
La soustraction de 7 signifie que les initiales peuvent être supprimées et les 2 dernières peuvent être supprimées sans aucun travail supplémentaire. Cette suppression signifie que certaines entrées non valides peuvent entraîner une lecture de mémoire non valide, ce qui peut entraîner une erreur de segmentation sur des images particulières.
Usage:
Pour y mettre les images, j'ai écrit un wrapper en utilisant libpng. Il s'avère également que malgré le nom de fichier, les images de la question sont en fait des jpeg (!), Vous devrez donc les exporter manuellement en tant que pngs.
Panne
la source
Mathematica
1170 1270 1096 1059 650 528 570 551 525498 octetsLa dernière version économise 27 octets en n'exigeant pas que la plaque soit "découpée" avant d'être analysée. L'avant-dernière version a économisé 26 octets en utilisant seulement 10 des 24 points d'échantillonnage d'origine.
122 octets enregistrés grâce à l'idée de LegionMammal978 de regrouper la longue liste de numéros de base 10 en un seul numéro de base 36. Il a analysé encore 20 octets du code final.
Le saut de 528 à 570 octets était dû à un code supplémentaire pour s'assurer que l'ordre des lettres retournées correspondait à l'ordre des lettres sur la plaque d'immatriculation. Le centroïde de chaque lettre contient la coordonnée x, qui révèle les positions relatives des lettres le long de x.
Code non golfé
Aperçu
L'idée de base est de vérifier si un échantillonnage systématique des pixels de l'image d'entrée correspond aux pixels du même emplacement sur les images authentiques. Une grande partie du code se compose des signatures de bits pour chaque caractère,
Le diagramme montre les pixels qui sont échantillonnés à partir des lettres "J", "P", "Q" et "R".
Les valeurs des pixels peuvent être représentées sous forme de matrices. Les sombres et les gras
1
correspondent aux cellules noires. Les0
correspond aux globules blancs.Ce sont les règles de remplacement du déchiffrement pour 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"
Il devrait être possible de comprendre pourquoi la règle pour "0" est:
{15, 9, 9, 9, 9, 15} -> "0"
et donc distinguable de la lettre "Q".
Ce qui suit montre les 10 points utilisés dans la version finale. Ces points sont suffisants pour identifier tous les personnages.
Que font les fonctions
plateCrop[img]
supprime le cadre et le bord gauche de la plaque, rend l'arrière-plan blanc. J'ai pu éliminer cette fonction de la version finale en sélectionnant des composants d'image, des lettres possibles d'une hauteur comprise entre 100 et 120 pixels.isolateLetters[img]
supprime les lettres individuelles de l'image recadrée.Nous pouvons montrer comment cela fonctionne en montrant où l'image recadrée, sortie de
plateCrop
va comme entrée pourisolateLetters
. La sortie est une liste de caractères individuels.Coordinates
sont 24 positions uniformément réparties pour vérifier la couleur des pixels. Les coordonnées correspondent à celles de la première figure.{{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
convertit les pixels en binaire.codes
sont la signature de chaque personnage. Les valeurs décimales sont des abréviations du code binaire pour les cellules noires (0) et blanches (1). Dans la version golf, la base 36 est utilisée.(*
decryptRules
sont pour remplacer les signatures par leur caractère respectif *)f
est la fonction qui prend une image d'une plaque d'immatriculation et renvoie une lettre.{"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"}
Golfé
Le code est raccourci en utilisant un seul nombre décimal pour représenter les 24 bits (blancs ou noirs) pour chaque caractère. Par exemple, la lettre « J » utilise la règle de remplacement suivant:
1118623 -> "J"
.1118623 correspond à
{0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1}
qui peut être reconditionné comme
{{0, 0, 0, 1}, {0, 0, 0, 1}, {0, 0, 0, 1}, {0, 0, 0, 1}, {1, 0, 0, 1} , {1, 1, 1, 1}}
qui est simplement la matrice pour "J" que nous avons vue ci-dessus.
Une autre économie vient de la représentation de l'alphabet
"0123456789ABCDEFGHJKLMNPQRSTUVWXYZ"
plutôt que d'une liste de lettres.Enfin, toutes les fonctions de la version longue, sauf
h
, ont été intégrées à la fonctionf
plutôt que définies séparément.la source
{1118623, 2518818, ..., 16645599}
par ceci .x[[All,2,1]]
peut être remplacé parx[[;;,2,1]]
.Flatten[x,1]
est équivalent àJoin@@x
, etFlatten[#,1]&/@x
est équivalent àJoin@@@x
. Il y a quelques autres optimisations mineures qui peuvent être faites. Le code de 551 octets après ces golfs.C #,
10401027 octetsNon golfé:
Fondamentalement, j'ai trouvé des points de référence spécifiques pour vérifier le jaune / noir afin de déterminer l'identité de chaque personnage.
la source
csc.exe main.cs /r:System.Drawing.dll
PHP -
174116741143 octetsIl a d'abord été mis en place en apprenant les profils des personnages à partir des premiers exemples, qui ont ensuite résumé chaque personnage en six chiffres. J'ai choisi six parce que j'en avais à l'origine cinq, et cela n'a pas fonctionné aussi bien que je le souhaiterais, mais six semble fonctionner beaucoup mieux. Une grande partie de l'optimisation consiste à compresser ces profils en nombres d'octets de plus en plus petits.
Le premier et le deuxième profil
*lhdfdn
et|nnmmkk
sont en fait la goutte bleue avec "GB" en bas*
, et la bordure droite|
, que nous ignorons. Il est plus sûr de les inclure afin que la goutte et la bordure droite aient quelque chose à faire correspondre.Devrait gérer n'importe quel format d'image, toute mise à l'échelle raisonnable à condition que le rapport d'aspect ne change pas trop, aucune couleur foncée sur claire, et même un peu de bruit et d'ombrage!
Il a besoin de la bordure, au moins en haut et en bas, cela fait partie du profil.
Enregistrez sous
ocr.php
, puis exécutez à partir de la ligne de commande:Pour ceux qui sont intéressés, voici le code d'apprentissage. Enregistrez sous
learn.php
et exécutez à partir de la ligne de commande, aucun argument.la source
PHP,
971970 octetsS'inspire largement de la réponse de Yimin Rong , qui peut être sérieusement minimisée, en particulier les indices de tableau, et placée dans un Phar avec compression gzip.
Téléchargez le phar
Ceci est ma version de base améliorée à
15571535 octets, enregistrée simplement sous le nom de fichier "o":Améliorations:
1ère étape
2e étape
intval
par~~
(enregistre 8 octets, deux occurrences)file_get_contents($u)
remplacé parjoin('',file($u))
(économise 5 octets)Malheureusement, toutes les améliorations de la deuxième étape ne se traduisent qu'en 1 octet de code moins compressé. :-RÉ
Et ce code a été utilisé pour créer le Phar:
Testez avec
php ocr.phar http://i.imgur.com/i8jkCJu.png
ou toute autre image du scénario de test.la source