Ich würde gerne wissen, wie ich mit OpenCV auf meiner Videokamera ein Bild erkennen kann. Das Bild kann eines von 500 Bildern sein.
Was ich gerade mache:
%Vor%Die Bilder, die ich entdecken möchte, sind 2-5kb klein. Wenige haben Text auf ihnen, aber andere sind nur Zeichen. Hier ein Beispiel:
Weißt du, wie ich das machen kann?
Es gibt verschiedene Dinge hier drin. Ich werde Ihr Problem aufschlüsseln und Sie auf einige mögliche Lösungen hinweisen.
Klassifizierung : Ihre Hauptaufgabe besteht darin, festzustellen, ob ein bestimmtes Bild zu einer Klasse gehört. Dieses Problem selbst kann in mehrere Probleme zerlegt werden:
Feature-Repräsentation Sie müssen entscheiden, wie Sie Ihr Feature modellieren möchten , dh wie werden Sie jedes Bild in einem Feature-Raum darstellen, so dass Sie einen Klassifikator trainieren können, um diese Klassen zu trennen. Die Feature-Repräsentation selbst ist bereits eine große Designentscheidung. Man könnte (i) das Histogramm der Bilder mit n Behältern berechnen und einen Klassifikator trainieren oder (ii) Sie könnten einen auswählen Sequenz von zufälligen Patches Vergleich wie in einer zufälligen Gesamtstruktur. Nach dem Training müssen Sie jedoch die Leistung Ihres Algorithmus bewerten, um zu sehen, wie gut Ihre Entscheidung war.
Es gibt ein bekanntes Problem namens Überarbeiten , bei dem Sie zu gut lernen, dass Sie nicht verallgemeinern können dein Klassifikator. Dies kann normalerweise mit Kreuzvalidierung vermieden werden. Wenn Sie nicht mit dem Konzept von falsch positiv oder falsch negativ vertraut sind, werfen Sie einen Blick in diesen Artikel .
Sobald Sie Ihren Feature-Space definiert haben, müssen Sie einen Algorithmus zum Trainieren dieser Daten auswählen. Dies könnte als Ihre größte Entscheidung angesehen werden. Es gibt mehrere Algorithmen, die jeden Tag herauskommen. Um einige der klassischen zu nennen: Naive Bayes , SVM , Random Forests , und in jüngerer Zeit hat die Community großartige Ergebnisse mit
Patches : Nun haben Sie erwähnt, dass Sie die Bilder auf Ihrer Webcam erkennen möchten. Wenn Sie die Bilder drucken und in einem Video anzeigen möchten, müssen Sie mehrere Dinge handhaben. Es ist notwendig, Patches auf Ihrem großen Bild (Eingabe von der Webcam) zu definieren, in denen Sie eine Feature-Repräsentation für jeden Patch erstellen und auf die gleiche Weise wie im vorherigen Schritt klassifizieren. Um dies zu tun, könnten Sie ein Fenster verschieben und alle Patches klassifizieren, um zu sehen, ob sie zur negativen oder zu einer der positiven Klassen gehören. Es gibt andere Alternativen.
Skalierung : Wenn Sie in der Lage sind, die Position von Bildern im großen Bild zu erkennen und zu klassifizieren, besteht der nächste Schritt darin, die Spielzeugannahme von Fixes-Skalierung zu lockern. Um einen Multiskalen-Ansatz zu behandeln, könnten Sie eine Pyramide erstellen, mit der Sie die Erkennung in mehreren Auflösungen durchführen können. Alternative Ansätze könnten Schlüsselpunktdetektoren wie SIFT und SURF . In SIFT gibt es eine Bildpyramide, die die Invarianz erlaubt.
Projektion Bis jetzt haben wir angenommen, dass Sie Bilder unter orthographischer Projektion haben, aber höchstwahrscheinlich werden Sie leichte perspektivische Projektionen haben, die die ganze vorherige Annahme zum Scheitern bringen werden. Eine naive Lösung wäre beispielsweise, die Ecken des weißen Hintergrunds Ihres Bildes zu erkennen und das Bild zu korrigieren, bevor Sie den Merkmalsvektor für die Klassifizierung erstellen. Wenn Sie SIFT oder SURF verwendet haben, könnten Sie eine Methode entwickeln, die es vermeidet, diese explizit zu behandeln. Wenn Ihre Eingabe jedoch nur aus Quadraten besteht, wie in ARToolkit , würde ich mich für eine manuelle Korrektur entscheiden.
Ich hoffe, ich habe Ihnen ein besseres Bild von Ihrem Problem gegeben.
Ich würde die Verwendung von SURF dafür empfehlen, da Bilder sich in verschiedenen Entfernungen von Ihrer Kamera befinden können, d. h. die Skala ändern. Ich hatte ein ähnliches Experiment und SURF arbeitete genau wie erwartet. Aber SURF hat eine sehr schwierige Anpassung (und teure Operationen), Sie sollten verschiedene Setups ausprobieren, bevor Sie die benötigten Ergebnisse erhalten.
Hier ist ein Link: Ссылка
Youtube-Video (in C #, kann aber eine Idee geben): Ссылка
Ich bin möglicherweise nicht qualifiziert genug, um dieses Problem zu lösen. Das letzte Mal, als ich OpenCV ernsthaft benutzte, war es immer noch 1.1. Aber nur ein wenig darüber nachgedacht und hoffe, es würde helfen (derzeit interessiere ich mich für DIP und ML).
Ich denke, es wird wahrscheinlich eine einfachere Aufgabe sein, wenn Sie nur ein Bild klassifizieren müssen, wenn das Bild nur eines von Ihren 500 Bildern ist (oder sehr ähnlich ist). Dafür könntest du SVM oder ein neurales Netzwerk benutzen (Felix hat bereits eine ausgezeichnete Aufzählung dazu gegeben).
Ihr Problem scheint jedoch zu sein, dass Sie dieses Kandidatenbild zuerst in Ihrer Webcam finden müssen, deren Ort Sie vorher noch nicht genau kennen. (lassen Sie uns wissen, ob es so ist. Ich denke, es ist wichtig.)
Wenn ja, ist das schwierigere Problem die Erkennung / Lokalisierung Ihres Kandidatenbildes. Ich habe dafür keine allgemeine Lösung. Das erste, was ich tun würde, ist zu sehen, ob es ein gemeinsames Merkmal in Ihren 500 Bildern gibt (z. B. ob alle von einem roten Kreis eingeschlossen sind oder die Hälfte von ihnen einen Kreis und die andere Hälfte ein Rechteck aufweist). Wenn dies getan werden kann, wird das Problem einfacher (es wäre ähnlich Gesichtserkennung Problem, die eine gute Lösung haben).
Mit anderen Worten bedeutet dies, dass Sie zuerst die 500 Bilder in ein paar Gruppen mit gemeinsamem Merkmal (nach Mensch) klassifizieren und die Gruppe zuerst erkennen, dann skalieren und die oben erwähnte Technik verwenden, um sie in feine Ergebnisse zu klassifizieren. Auf diese Weise wird es rechnerisch akzeptabler sein, als 500 Bilder nacheinander zu erkennen.
Übrigens würde dieses PPT helfen, einen visuellen Hinweis darauf zu geben, was bei der Merkmalsextraktion und dem Bildvergleich vor sich geht Ссылка .
Detect vs recognize: Das Bild wird nur im Hintergrund gefunden, und aus Ihren Kommentaren wurde mir klar, dass Sie möglicherweise vom Hintergrund umgeben sind. Es kann Ihren Algorithmus erleichtern, wenn Sie Ihre Zeichen aus dem Hintergrund (Erkennung) irgendwie zuschneiden können, bevor Sie versuchen, sie zu erkennen. Das Erkennen ist eine nächste Stufe, die annimmt, dass Sie das zugeschnittene Bild korrekt wie das vorher gesehene klassifizieren können.
Wenn Sie Echtzeitgeschwindigkeit und Skalierungs- / Rotationsinvarianz benötigen, wird weder SIFT no SURF dies schnell tun. Heutzutage kann man viel besser machen, wenn man die Last der Bildverarbeitung auf eine Lernstufe verlagert, wie es Leprit . Kurz, er unterwarf jedes Muster einer Reihe von affinen Transformationen und trainierte einen binären Klassifikationsbaum, um jeden Punkt korrekt zu erkennen, indem er viele binäre Vergleichstests durchführte. Bäume sind extrem schnell und ein Weg zu gehen, ganz zu schweigen davon, dass der Großteil der Verarbeitung offline erfolgt. Diese Methode ist auch gegenüber Rotationen außerhalb der Ebene robuster als SIFT oder SURF. Sie werden auch über die Baumklassifizierung erfahren, die Ihnen die letzte Verarbeitungsstufe erleichtern kann.
Schließlich basiert eine Erkennungsstufe nicht nur auf der Anzahl der Übereinstimmungen, sondern auch auf ihrer geometrischen Konsistenz. Da Ihre Zeichen flach aussehen, empfehle ich, entweder affine oder Homogra- fietransformationen zu finden, die die meisten In- lierfaktoren enthalten, wenn sie zwischen übereinstimmenden Punkten berechnet werden.
Wenn Sie sich Ihren Code ansahen, wurde mir klar, dass Sie keiner dieser Empfehlungen folgen sollten. Es kann ein guter Ausgangspunkt für Sie sein, über Entscheidungsbäume zu lesen und dann mit einigen Beispielen zu spielen Code (siehe pilot.cpp im oben genannten Link)
Tags und Links objective-c c++ opencv ios augmented-reality