Siehe auch: Parsen
Einführung
Sie arbeiten in einem staatlichen Programmierteam, das die Radarkameras programmiert hat. Die Gruppe der Personen, die den Geschwindigkeitsrechner programmiert haben, hat jedoch zu viel Platz in Anspruch genommen, sodass Sie die Kennzeichenerkennungssoftware so klein wie möglich halten müssen.
Herausforderung
Geben Sie den Text auf dem Nummernschild zurück, wenn Sie ein Bild von einem Nummernschild erhalten haben.
Kennzeichen
Das Folgende sind alle Zeichen, die Ihr Programm erkennen muss:
ABCDEFG
H1JKLMN0
PQRSTUVW
XYZ01234
56789
Hinweis
Auf britischen Nummernschildern sind die Zeichen für I (i) und 1 (eins) gleich und die Zeichen für O (o) und 0 (null) gleich. Nehmen Sie aus diesem Grund immer an, dass Zeichen die Zahlen sind. Dh das folgende Nummernschild ist 10 (eine Null):
Beispiele
C0D3 GLF
B3T4 DCY
M1NUS 15
YET1CGN
Andere Regeln
Internetzugang und OCR-Bibliotheken und -Funktionen sind nicht zulässig.
Die Nummernschilder sehen immer identisch mit den oben gezeigten aus. Alle Nummernschilder haben ungefähr die gleiche Größe (aufgrund der Beschneidungsmethode kann es zu Ungenauigkeiten kommen).
Wenn Sie verlustfreie PNG-Versionen eines Nummernschilds benötigen, werde ich Ihnen diese zur Verfügung stellen.
Wertung
Das kürzeste Programm in Bytes gewinnt.
Alle Nummernschilder sind Screenshots der Suchleiste auf dieser Site
quelle
Antworten:
C, 409 Bytes (und ich bin genauso überrascht wie jeder andere)
Nimmt als Eingabe: die Breite (
w
) und Höhe (h
) des Bildes, gefolgt von den gepackten RGB-Daten als Array vonchar
s (d
). Alle anderen Funktionsparameter sind getarnte Variablendeklarationen. Ignoriert alles außer dem grünen Kanal und wendet als ersten Durchgang einen Schwellenwert von 32 an.Meistens die gleiche Methode wie bei @ DavidC, mit der Ausnahme, dass überprüft wird, ob mindestens 35% der einzelnen Probenfelder gefüllt sind. Hoffentlich ist es dadurch robuster, Änderungen zu skalieren, aber wer weiß.
Ich habe eine Brute-Force-Methode verwendet, um herauszufinden, welche Resampling-Größe und welcher Coverage-Prozentsatz für die beste Zuverlässigkeit zu verwenden sind (dh die wenigsten Fälle eines Zeichens mit mehreren Interpretationen). Es stellte sich heraus, dass ein 4x5-Raster mit 35% Deckung am besten war. Ich habe dann eine zweite Brute-Force-Methode verwendet, um die beste Bitanordnung und den besten Modulowert zu berechnen, um die Zeichendaten in eine kurze Zeichenfolge zu packen - das untere Bit oben links, das in x und y zunimmt, wobei der Endwert% 101 gedreht ist am besten mit dieser Nachschlagetabelle:
Das Subtrahieren von 7 bedeutet, dass die Initialen entfernt werden können, und die letzten 2 können ohne zusätzliche Arbeit entfernt werden. Dieses Entfernen bedeutet, dass bestimmte ungültige Eingaben zu einem ungültigen Speicherlesevorgang führen können, sodass bei bestimmten Bildern ein Fehler auftreten kann.
Verwendung:
Um die Bilder hinein zu bekommen, habe ich einen Wrapper mit libpng geschrieben. Es stellt sich auch heraus, dass die Bilder in der Frage trotz des Dateinamens eigentlich JPEGs (!) Sind, sodass Sie sie zuerst manuell als PNGs exportieren müssen.
Nervenzusammenbruch
quelle
Mathematica
1170 1270 1096 1059 650 528 570 551 525498 BytesDie neueste Version spart 27 Byte, da die Platte vor dem Parsen nicht "zugeschnitten" werden muss. Die vorletzte Version sparte 26 Bytes, indem nur 10 der ursprünglich 24 Abtastpunkte verwendet wurden.
Durch die Idee von LegionMammal978, die lange Liste der Basis-10-Zahlen als einzelne Basis-36-Zahl zu packen, wurden 122 Byte gespeichert. Er hat weitere 20 Bytes vom endgültigen Code entfernt.
Der Sprung von 528 auf 570 Byte war auf zusätzlichen Code zurückzuführen, um sicherzustellen, dass die Reihenfolge der zurückgegebenen Buchstaben der Reihenfolge der Buchstaben auf dem Nummernschild entsprach. Der Schwerpunkt für jeden Buchstaben enthält die x-Koordinate, die die relativen Positionen der Buchstaben entlang x angibt.
Ungolfed Code
Überblick
Die Grundidee besteht darin, zu prüfen, ob eine systematische Abtastung von Pixeln aus dem Eingabebild mit Pixeln aus derselben Position auf den Originalbildern übereinstimmt. Ein Großteil des Codes besteht aus den Bit-Signaturen für jedes Zeichen.
Das Diagramm zeigt die Pixel, die aus den Buchstaben "J", "P", "Q" und "R" abgetastet wurden.
Die Pixelwerte können als Matrizen dargestellt werden. Die dunklen, fetten
1
entsprechen schwarzen Zellen. Die0
entsprechen weißen Zellen.Dies sind die Regeln zum Ersetzen der Entschlüsselung für 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"
Es sollte verständlich sein, warum die Regel für "0" lautet:
{15, 9, 9, 9, 9, 15} -> "0"
und somit vom Buchstaben "Q" unterscheidbar.
Das Folgende zeigt die 10 Punkte, die in der endgültigen Version verwendet wurden. Diese Punkte reichen aus, um alle Zeichen zu identifizieren.
Was machen die Funktionen?
plateCrop[img]
Entfernt den Rahmen und die linke Kante von der Platte, wird der Hintergrund weiß. Ich konnte diese Funktion aus der endgültigen Version entfernen, indem ich Bildkomponenten auswählte, mögliche Buchstaben, die zwischen 100 und 120 Pixel hoch waren.isolateLetters[img]
Entfernt die einzelnen Buchstaben aus dem zugeschnittenen Bild.Wir können anzeigen, wie es funktioniert, indem wir zeigen, wo das zugeschnittene Bild, das von ausgegeben wird,
plateCrop
als Eingabe für dientisolateLetters
. Die Ausgabe ist eine Liste einzelner Zeichen.Coordinates
24 gleichmäßig verteilte Positionen zur Überprüfung der Pixelfarbe. Die Koordinaten entsprechen denen in der ersten Abbildung.{{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
wandelt die Pixel in Binär um.codes
sind die Signatur für jedes Zeichen. Die Dezimalwerte sind Abkürzungen des Binärcodes für schwarze (0) und weiße (1) Zellen. In der Golfversion wird die Basis 36 verwendet.(*
decryptRules
dienen zum Ersetzen von Signaturen durch die entsprechenden Zeichen *)f
ist die Funktion, die ein Bild von einem Nummernschild erstellt und einen Buchstaben zurückgibt.{"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 gespielt
Der Code wird mit einer einzelnen Dezimalzahl gekürzt, um alle 24 Bits (weiß oder schwarz) für jedes Zeichen darzustellen. Zum Beispiel verwenden die Buchstaben „J“ die folgende Ersetzungsregel:
1118623 -> "J"
.1118623 entspricht
{0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1}
die kann als umgepackt werden
{{0, 0, 0, 1}, {0, 0, 0, 1}, {0, 0, 0, 1}, {0, 0, 0, 1}, {1, 0, 0, 1} , {1, 1, 1, 1}}
Das ist einfach die Matrix für "J", die wir oben gesehen haben.
Eine weitere Einsparung ergibt sich aus der Darstellung des Alphabets
"0123456789ABCDEFGHJKLMNPQRSTUVWXYZ"
anstelle einer Buchstabenliste.Schließlich wurden alle Funktionen aus der Langversion, mit Ausnahme
h
der Funktion, in die Funktion integriertf
und nicht separat definiert.quelle
{1118623, 2518818, ..., 16645599}
mit diesem zu ersetzen .x[[All,2,1]]
kann durch ersetzt werdenx[[;;,2,1]]
.Flatten[x,1]
ist gleichbedeutend mitJoin@@x
undFlatten[#,1]&/@x
ist gleichbedeutend mitJoin@@@x
. Es gibt noch ein paar kleinere Optimierungen, die durchgeführt werden können. Der 551-Byte-Code nach diesen Golfspielen.C #,
10401027 BytesUngolfed:
Grundsätzlich habe ich einige spezifische Bezugspunkte gefunden, um gelb / schwarz zu prüfen, um die Identität jedes Zeichens zu bestimmen.
quelle
csc.exe main.cs /r:System.Drawing.dll
PHP -
174116741143 BytesEs wurde zuerst eingerichtet, indem die Profile der Zeichen aus den ersten Beispielen gelernt wurden, die dann jedes Zeichen in sechs Zahlen zusammenfassten. Ich habe sechs gewählt, weil ich ursprünglich fünf hatte, und es hat nicht so gut funktioniert, wie ich es gerne hätte, aber sechs scheint viel besser zu funktionieren. Ein Großteil der Optimierung besteht darin, diese Profile in immer kleinere Bytezahlen zu zerlegen.
Das erste und das zweite Profil
*lhdfdn
und|nnmmkk
sind eigentlich die blaue Klecks mit „GB“ am unteren Rand*
, und die rechte Grenze|
, die wir ignorieren. Es ist sicherer, sie einzuschließen, damit der Blob und der rechte Rand etwas haben, mit dem sie verglichen werden können.Sollte mit jedem Bildformat und jeder angemessenen Skalierung fertig werden, vorausgesetzt, das Seitenverhältnis ändert sich nicht zu stark, dunkle und helle Farben und sogar ein bisschen Rauschen und Schattierung!
Es braucht den Rand, zumindest oben und unten, der Teil des Profils ist.
Speichern unter
ocr.php
und dann über die Befehlszeile ausführen:Für diejenigen, die interessiert sind, ist hier der Lerncode. Speichern Sie als
learn.php
und führen Sie in der Befehlszeile keine Argumente aus.quelle
PHP,
971970 BytesGreift stark auf Yimin Rong ‚s Antwort , die ernsthaft golfed gelegt werden kann, vor allem den Array - Indizes, und in eine Phar mit gzip - Kompression.
Laden Sie den phar herunter
Dies ist meine verbesserte Basisversion mit
1557 bis1535 Bytes, die einfach unter dem Dateinamen "o" gespeichert wurde:Verbesserungen:
1. Stufe
2. Stufe
intval
durch~~
(spart 8 Bytes, zwei Vorkommen)file_get_contents($u)
ersetzt durchjoin('',file($u))
(spart 5 Bytes)Leider werden alle Verbesserungen der zweiten Stufe nur in 1 Byte weniger gezippten Code übersetzt. :-D
Und dieser Code wurde verwendet, um den Phar zu erstellen:
Testen Sie mit
php ocr.phar http://i.imgur.com/i8jkCJu.png
oder einem anderen Testfallbild.quelle