2012-04-04 15 views
10

Ich versuche, Buchstaben von einem Spielbrett für ein Projekt zu extrahieren. Derzeit kann ich das Spielbrett erkennen, es in die einzelnen Quadrate segmentieren und Bilder von jedem Quadrat extrahieren.Genaue binäre Bildklassifizierung

Der Eingang Ich ist wie diese bekommen (diese sind einzelne Buchstaben):

enter image description hereenter image description hereenter image description hereenter image description hereenter image description hereenter image description here

Zuerst war ich die Anzahl der schwarzen Pixel pro Bild zu zählen und die Verwendung dieser als eine Möglichkeit, die verschiedenen Buchstaben zu identifizieren, was bei kontrollierten Eingabebildern gut funktioniert hat. Das Problem, das ich habe, ist jedoch, dass ich diese Arbeit nicht für Bilder machen kann, die etwas davon abweichen.

Ich habe etwa 5 Proben von jedem Brief mit dem Training zu arbeiten, die gut genug sein sollte.

Weiß jemand, was wäre ein guter Algorithmus für diesen Zweck?

waren Meine Ideen (nach der Bild Normalisierung):

  • den Unterschied zwischen einem Bild Zählen und jedem Buchstaben Bild zu sehen, welche die geringste Menge an Fehler erzeugt. Dies funktioniert jedoch nicht für große Datasets.
  • Erkennen von Ecken und Vergleichen der relativen Positionen.
  • ???

Jede Hilfe wäre willkommen!

+2

Willkommen bei OCR. – delnan

+0

Heh, ich habe Teschearact auf den Testbildern getestet, nachdem ich sie ein wenig erweitert habe, aber es ist kläglich gescheitert (selbst nachdem ich den Segmentierungsmodus auf "ein Wort" eingestellt habe). OCR erscheint für diesen speziellen Fall wie ein Overkill, IMO, da die Bilder in jedem Fall sehr ähnlich sind. – Blender

+1

Was ist mit Skalen- und Rotationsinvarianz? – moooeeeep

Antwort

13

Ich denke, das eine Art von beaufsichtigte Lernen ist. Sie müssen einige Merkmale auf den Bildern extrahieren und dann Ihre Klassifizierung auf der Grundlage des Merkmalsvektors vornehmen, den Sie für jedes Bild berechnet haben.

Feature Extraction

Auf den ersten Blick, dass Feature Extraction Teil sieht aus wie ein gutes Szenario für Hu-Moments. Berechnen Sie einfach die image moments, dann berechnen Sie cv::HuMoments von diesen. Dann haben Sie einen 7-dimensionalen reellen Merkmalsraum (ein Merkmalsvektor pro Bild). Alternativ können Sie diesen Schritt überspringen und jeden Pixelwert als separate Funktion verwenden. Ich denke, der Vorschlag in this answer geht in diese Richtung, aber fügt eine PCA-Komprimierung hinzu, um die Dimensionalität des Feature-Speicherplatzes zu reduzieren.

Klassifizierung

Was die Klassifizierung Teil können Sie fast jede Klassifikationsalgorithmus Sie mögen. Sie könnten eine SVM für jeden Buchstaben verwenden (binäre Ja-Nein-Klassifizierung), Sie könnten einen NaiveBayes (was der maximal wahrscheinliche Buchstabe ist) verwenden, oder Sie könnten einen k-NearestNeighbor (kNN, minimaler räumlicher Abstand im Merkmalsraum) Ansatz verwenden, z.B flann.

Speziell für entfernungsbasierte Klassifizierer (z. B. kNN) sollten Sie eine Normalisierung Ihres Merkmalsraums in Betracht ziehen (z. B. alle Dimensionswerte auf einen bestimmten Bereich für euklidische Distanz skalieren oder Dinge wie Mahalanobis-Distanz verwenden). Dies dient dazu, Merkmale mit großen Wertunterschieden im Klassifizierungsprozess nicht zu überrepräsentieren.

Bewertung

Natürlich können Sie Trainingsdaten benötigen, dh Bilder Merkmalsvektoren den richtigen Buchstaben angegeben. Und ein Prozess, um Ihren Prozess, z. Kreuzvalidierung


In diesem Fall möchten Sie vielleicht auch einen Blick auf template matching haben. In diesem Fall würden Sie das Kandidatenbild mit den verfügbaren Mustern in Ihrem Trainingssatz zusammenfalten. Hohe Werte im Ausgabebild zeigen eine gute Wahrscheinlichkeit an, dass sich das Muster an dieser Position befindet.

+0

Vielen Dank für Ihre Hilfe! Ich bin soweit gekommen, die Hu-Momente für die einzelnen Bilder zu berechnen, aber danach hat mich die Klassifizierung mit vielen Fehlern überhäuft. Hoffentlich kann ich es am nächsten Tag zur Arbeit bringen und sehen, wie gut es funktioniert! – Blender

+0

Habe gerade den Klassifikator zum arbeiten bekommen! Es ist 100% genau für meine Trainingsdaten (duh), hat aber Probleme mit neuen Eingaben. Ich werde es mit genaueren Proben noch etwas trainieren. – Blender

+0

@Blender - froh das hat geholfen! – moooeeeep

5

Dies ist ein Erkennungsproblem. Ich würde persönlich eine Kombination von PCA und eine maschinelle Lerntechnik (wahrscheinlich SVM) verwenden. Diese sind ziemlich große Themen so ich fürchte, ich kann nicht wirklich zu viel erarbeiten, aber hier ist das sehr grundlegende Prozess:

  1. Sammeln Sie Ihre Trainingsbilder (mehr als ein Brief, aber nicht verrückt werden)
  2. beschriften (könnte eine Menge Dinge bedeuten, in diesem Fall bedeutet es Gruppe die Buchstaben in logische Gruppen - Alle A Bilder -> 1, alle B-Bilder -> 2, etc.)
  3. Trainieren sie Ihre Klassifikator
    • Führen Sie alles durch PCA-Zerlegung
    • Projizieren Sie alle Ihre Trainingsbilder in PCA Raum
    • Führen Sie die projizierten Bilder durch eine SVM (wenn es ein One-Klasse-Klassifikator, tun sie einer nach dem anderen, so dass sie sonst tun alle auf einmal.)
    • Speichern Sie Ihre PCA Eigenvektor und SVM Trainingsdaten
  4. Run Anerkennung
    • Last in Ihrem PCA Raum
    • Last in Ihrem SVM Trainingsdaten
    • Für jedes neue Bild, Projekt es in PCA Raum und fragen sie Ihren SVM es zu klassifizieren.
    • Wenn Sie eine Antwort erhalten (eine Nummer), ordnen Sie sie einem Buchstaben zu (1 -> A, 2 -> B, usw.).
+0

Vielen Dank! Ich lese jetzt gerade PCA. Endlich eine Verwendung für Lineare Algebra ... – Blender

4
+0

Ich lese die zweite durch und ich scheine das schon zu tun (vergleiche verschiedene Pixel und finde das Bild, das diesen Fehler minimiert). Der erste ist ein bisschen versteckt und erklärt nicht, was sehr gut passiert, aber danke für die Links! Ich werde ein wenig nachforschen, wie das erste funktioniert. – Blender

2

Ich hatte ein ähnliches Problem vor ein paar Tagen. Aber es war Ziffernerkennung. Nicht für Alphabete.

Und ich implementierte eine einfache OCR dafür mit kNearestNeighbour in OpenCV.

Unten finden Sie den Link und Code:

Simple Digit Recognition OCR in OpenCV-Python

implementieren es für Alphabete. Hofft, es funktioniert.

+0

Diese Antwort war * wirklich * hilfreich, als ich die Algorithmen tatsächlich kodierte. Vielen Dank! – Blender

0

können Sie versuchen, ein Modell bauen, indem Sie Ihre Trainingsdaten hochladen (~ 50 Bilder von 1s, 2s, 3s .... 9s) zu demo.nanonets.ai (kostenlos zu benutzen)

1) Laden Sie Daten Ihrer Ausbildung hier:

demo.nanonets.ai

2) Dann die API abfragen, um den folgenden (Python-Code) mit:

import requests 
import json 
import urllib 
model_name = "Enter-Your-Model-Name-Here" 
url = "http://images.clipartpanda.com/number-one-clipart-847-blue-number-one-clip-art.png" 
files = {'uploadfile': urllib.urlopen(url).read()} 
url = "http://demo.nanonets.ai/classify/?appId="+model_name 
r = requests.post(url, files=files) 
print json.loads(r.content) 

3) die Antwort wie folgt aussieht:

{ 
    "message": "Model trained", 
    "result": [ 
    { 
     "label": "1", 
     "probability": 0.95 
    }, 
    { 
     "label": "2", 
     "probability": 0.01 
    }, 

    .... 

    { 
     "label": "9", 
     "probability": 0.005 
    } 
    ] 
}