c++ opencv - Bildverarbeitung:Algorithmus Verbesserung für "Coca-Cola Can" Anerkennung



image processing (21)

Eines der interessantesten Projekte, an denen ich in den letzten Jahren gearbeitet habe, war ein Projekt über Bildverarbeitung . Das Ziel war, ein System zu entwickeln, um Coca-Cola -Dosen erkennen zu können (beachten Sie, dass ich das Wort "Dosen" betone, Sie werden sehen, warum in einer Minute). Unten sehen Sie ein Beispiel, in dem die Dose im grünen Rechteck mit Skalierung und Drehung erkannt wird.

Einige Einschränkungen für das Projekt:

  • Der Hintergrund könnte sehr laut sein.
  • Die Dose könnte irgendeine Skalierung oder Rotation oder sogar Orientierung (innerhalb vernünftiger Grenzen) haben.
  • Das Bild könnte ein gewisses Maß an Unschärfe aufweisen (Konturen sind möglicherweise nicht ganz gerade).
  • Es könnte Coca-Cola-Flaschen im Bild sein, und der Algorithmus sollte nur die Dose erkennen !
  • Die Helligkeit des Bildes kann stark variieren (Sie können sich also nicht zu sehr auf die Farberkennung verlassen).
  • Die Dose könnte teilweise an den Seiten oder in der Mitte versteckt sein und möglicherweise teilweise hinter einer Flasche verborgen sein.
  • Es konnte überhaupt keine Dose in dem Bild geben, in diesem Fall musste man nichts finden und eine Nachricht schreiben, die das sagte.

Sie könnten also knifflige Dinge wie diesen haben (was in diesem Fall mein Algorithmus total gescheitert hat):

Ich habe dieses Projekt vor einer Weile gemacht und hatte eine Menge Spaß dabei, und ich hatte eine anständige Implementierung. Hier sind einige Details zu meiner Implementierung:

Sprache : Fertig in C ++ mit OpenCV- Bibliothek.

Pre-processing : Für die Bildvorverarbeitung, dh für die Umwandlung des Bildes in eine rohere Form, um den Algorithmus zu verwenden, habe ich 2 Methoden verwendet:

  1. Ändern der Farbdomäne von RGB zu HSV und Filtern basierend auf "rotem" Farbton, Sättigung über einem bestimmten Schwellenwert, um orangefarbene Farben zu vermeiden, und Filtern mit niedrigem Wert, um dunkle Töne zu vermeiden. Das Endergebnis war ein binäres Schwarzweißbild, bei dem alle weißen Pixel die Pixel darstellten, die diesem Schwellenwert entsprachen. Offensichtlich gibt es immer noch eine Menge Mist im Bild, aber das reduziert die Anzahl der Dimensionen, mit denen Sie arbeiten müssen.
  2. Rauschfilterung unter Verwendung der Medianfilterung (wobei der mittlere Pixelwert aller Nachbarn genommen wird und das Pixel durch diesen Wert ersetzt wird), um Rauschen zu reduzieren.
  3. Verwenden Sie Canny Edge Detection Filter , um die Konturen aller Elemente nach 2 vorhergehenden Schritten zu erhalten.

Algorithmus : Der Algorithmus selbst, den ich für diese Aufgabe gewählt habe, stammt aus this genialen Buch über die Merkmalsextraktion und heißt verallgemeinerte Hough-Transformation (ziemlich verschieden von der regulären Hough-Transformation). Es sagt im Grunde ein paar Dinge:

  • Sie können ein Objekt im Raum beschreiben, ohne seine analytische Gleichung zu kennen (was hier der Fall ist).
  • Es ist resistent gegen Bildverformungen wie Skalierung und Rotation, da es Ihr Bild grundsätzlich auf jede Kombination aus Skalierungsfaktor und Rotationsfaktor testet.
  • Es verwendet ein Basismodell (eine Vorlage), das der Algorithmus "lernt".
  • Jedes Pixel, das im Konturbild verbleibt, wird für ein anderes Pixel stimmen, das vermutlich das Zentrum (in Bezug auf die Schwerkraft) Ihres Objekts sein wird, basierend auf dem, was es aus dem Modell gelernt hat.

Am Ende erhält man eine Heatmap der Stimmen, zum Beispiel werden hier alle Pixel der Kontur der Dose für ihr Gravitationszentrum stimmen, also wirst du viele Stimmen in dem gleichen Pixel haben, das dem entspricht zentrieren und sehen einen Peak in der Heatmap wie folgt:

Sobald Sie das haben, kann Ihnen eine einfache threshold-basierte Heuristik die Position des zentralen Pixels geben, aus der Sie die Skalierung und Rotation ableiten und dann Ihr kleines Rechteck um sie zeichnen können (Endwert und Rotationsfaktor sind natürlich relativ zu Ihrem Originalvorlage). In der Theorie zumindest ...

Ergebnisse : Während dieser Ansatz in den grundlegenden Fällen funktionierte, fehlte er in einigen Bereichen stark:

  • Es ist extrem langsam ! Ich betone das nicht genug. Fast ein ganzer Tag war nötig, um die 30 Testbilder zu verarbeiten, offensichtlich weil ich einen sehr hohen Skalierungsfaktor für Rotation und Translation hatte, da einige der Dosen sehr klein waren.
  • Es war völlig verloren, wenn Flaschen im Bild waren, und aus irgendeinem Grund fand fast immer die Flasche statt der Dose (vielleicht weil Flaschen größer waren, hatte also mehr Pixel, also mehr Stimmen)
  • Fuzzy-Bilder waren auch nicht gut, da die Stimmen in Pixeln an zufälligen Orten um das Zentrum herum landeten und so mit einer sehr lauten Heat Map endeten.
  • Invarianz in Translation und Rotation wurde erreicht, aber nicht in Ausrichtung, was bedeutet, dass eine Dose, die nicht direkt auf das Kameraobjektiv gerichtet war, nicht erkannt wurde.

Können Sie mir helfen, meinen speziellen Algorithmus zu verbessern, indem Sie ausschließlich OpenCV- Funktionen verwenden, um die vier genannten spezifischen Probleme zu lösen?

Ich hoffe, dass einige Leute auch etwas daraus lernen werden, schließlich denke ich, dass nicht nur Leute, die Fragen stellen, lernen sollten. :)


Answers

If you are interested in it being realtime, then what you need is to add in a pre-processing filter to determine what gets scanned with the heavy-duty stuff. A good fast, very real time, pre-processing filter that will allow you to scan things that are more likely to be a coca-cola can than not before moving onto more iffy things is something like this: search the image for the biggest patches of color that are a certain tolerance away from the sqrt(pow(red,2) + pow(blue,2) + pow(green,2)) of your coca-cola can. Start with a very strict color tolerance, and work your way down to more lenient color tolerances. Then, when your robot runs out of an allotted time to process the current frame, it uses the currently found bottles for your purposes. Please note that you will have to tweak the RGB colors in the sqrt(pow(red,2) + pow(blue,2) + pow(green,2)) to get them just right.

Also, this is gona seem really dumb, but did you make sure to turn on -oFast compiler optimizations when you compiled your C code?


Ich kenne OpenCV nicht, aber wenn ich das Problem logisch betrachte, denke ich, dass man zwischen Flasche und Dose unterscheiden kann, indem man das Bild, nach dem man sucht, zB Coca Cola, ändert. Sie sollten bis zum oberen Teil der Dose integrieren, denn im Falle der Dose gibt es Silberfutter oben auf der Coca Cola und im Falle der Flasche wird es kein solches Silberfutter geben.

Aber offensichtlich wird dieser Algorithmus in Fällen fehlschlagen, in denen die Oberseite der Dose versteckt ist, aber in einem solchen Fall wird auch ein Mensch nicht in der Lage sein, zwischen den beiden zu unterscheiden (wenn nur Coca Cola-Teil der Flasche / Dose sichtbar ist)


Ich mag Ihre Frage, unabhängig davon, ob es sich um ein Thema handelt oder nicht: P

Eine interessante Seite; Ich habe gerade ein Fach in meinem Abschluss abgeschlossen, wo wir Robotik und Computer Vision behandelt haben. Unser Projekt für das Semester war dem von Ihnen beschriebenen sehr ähnlich.

Wir mussten einen Roboter entwickeln, der mit einer Xbox Kinect Cola-Flaschen und -Dosen bei jeder Orientierung in einer Vielzahl von Licht- und Umgebungsbedingungen erkennt. Unsere Lösung beinhaltete die Verwendung eines Bandpassfilters auf dem Hue-Kanal in Kombination mit der Hough-Circle-Transformation. Wir konnten die Umgebung ein wenig einschränken (wir konnten wählen, wo und wie wir den Roboter und den Kinect-Sensor positionieren), sonst würden wir die SIFT- oder SURF-Transformationen verwenden.

Sie können über unseren Ansatz in meinem Blogbeitrag zum Thema lesen :)


Sie benötigen ein Programm, das die Klassifizierungsgenauigkeit aus Erfahrung organisch lernt und verbessert.

Ich werde tiefes Lernen vorschlagen, mit tiefem Lernen wird das ein triviales Problem.

Sie können das Einführungsmodell v3 auf Tensorflow neu trainieren:

Wie man Inceptions letzte Ebene für neue Kategorien zurückholt .

In diesem Fall trainieren Sie ein konvolutionelles neuronales Netzwerk, um ein Objekt entweder als Coca-Cola-Dose zu klassifizieren oder nicht.


Dies kann eine sehr naive Idee sein (oder gar nicht funktionieren), aber die Abmessungen aller Koksdosen sind festgelegt. Wenn also das gleiche Bild sowohl eine Dose als auch eine Flasche enthält, dann können Sie sie nach Größenbetrachtungen unterscheiden (Flaschen werden größer). Aufgrund fehlender Tiefe (dh 3D-Mapping auf 2D-Mapping) ist es möglich, dass eine Flasche schrumpft und es keinen Größenunterschied gibt. Sie können einige Tiefeninformationen mithilfe von stereo-imaging wiederherstellen und dann die Originalgröße wiederherstellen.


Tiefes Lernen

Sammeln Sie mindestens ein paar hundert Bilder mit Cola-Dosen, kommentieren Sie die Bounding Box um sie herum als positive Klassen, enthalten Sie Cola-Flaschen und andere Cola-Produkte beschriften Sie negative Klassen sowie zufällige Objekte.

Wenn Sie nicht einen sehr großen Datensatz sammeln, sollten Sie den tiefen Einsatz von Deep Learning-Funktionen für kleine Datenmengen durchführen. Idealerweise eine Kombination von Support Vector Machines (SVM) mit tiefen neuronalen Netzen.

Sobald Sie die Bilder einem zuvor trainierten Deep-Learning-Modell (z. B. GoogleNet) zugeführt haben, verwenden Sie statt der Entscheidungsschicht (final) des neuronalen Netzwerks Klassifizierungen und verwenden Sie die Daten der vorherigen Ebene (n) als Funktionen zum Trainieren Ihres Klassifikators.

OpenCV und Google Net: http://docs.opencv.org/trunk/d5/de7/tutorial_dnn_googlenet.html

OpenCV und SVM: http://docs.opencv.org/2.4/doc/tutorials/ml/introduction_to_svm/introduction_to_svm.html


Form betrachten

Werfen Sie einen Blick auf die Form des roten Teils der Dose / Flasche. Beachten Sie, dass sich die Dose ganz oben leicht verjüngt, während das Flaschenetikett gerade ist. Sie können zwischen diesen beiden unterscheiden, indem Sie die Breite des roten Teils über seine Länge hinweg vergleichen.

Höhepunkte betrachten

Eine Möglichkeit, zwischen Flaschen und Dosen zu unterscheiden, ist das Material. Eine Flasche besteht aus Kunststoff, während eine Dose aus Aluminium besteht. In ausreichend gut ausgeleuchteten Situationen wäre die Betrachtung der Spekularität eine Möglichkeit, ein Flaschenetikett von einem Dosenetikett zu unterscheiden.

Soviel ich sagen kann, würde ein Mensch den Unterschied zwischen den beiden Arten von Etiketten unterscheiden. Wenn die Lichtverhältnisse schlecht sind, ist die Unterscheidung zwischen den beiden wahrscheinlich unsicher. In diesem Fall müssten Sie in der Lage sein, das Vorhandensein der transparenten / transluzenten Flasche selbst zu erkennen.


Wenn Sie nicht nur auf eine Kamera beschränkt sind, die sich nicht in einer Ihrer Beschränkungen befand, können Sie vielleicht einen Entfernungssensor wie die Xbox Kinect . Damit können Sie eine auf Tiefe und Farbe basierende angepasste Segmentierung des Bildes durchführen. Dies ermöglicht eine schnellere Trennung von Objekten in dem Bild. Sie können dann ICP-Matching- oder ähnliche Techniken verwenden, um die Form der Dose anzupassen, anstatt nur ihre Umrisse oder Farben, und wenn sie zylindrisch sind, kann dies eine gültige Option für jede Ausrichtung sein, wenn Sie eine vorherige 3D-Abtastung des Ziels haben. Diese Techniken sind oft ziemlich schnell, besonders wenn sie für einen bestimmten Zweck verwendet werden, der Ihr Geschwindigkeitsproblem lösen sollte.

Auch könnte ich vorschlagen, nicht unbedingt für Genauigkeit oder Geschwindigkeit, aber zum Spaß könnten Sie ein geschultes neuronales Netzwerk auf Ihrem hue segmentierten Bild verwenden, um die Form der Dose zu identifizieren. Diese sind sehr schnell und können oft bis zu 80/90% genau sein. Das Training ist jedoch ein wenig langwierig, da Sie die Dose in jedem Bild manuell identifizieren müssen.


Maybe too many years late, but nevertheless a theory to try.

The ratio of bounding rectangle of red logo region to the overall dimension of the bottle/can is different. In the case of Can, should be 1:1, whereas will be different in that of bottle (with or without cap). This should make it easy to distinguish between the two.

Update: The horizontal curvature of the logo region will be different between the Can and Bottle due their respective size difference. This could be specifically useful if your robot needs to pick up can/bottle, and you decide the grip accordingly.


Ich mag Darren Cooks und Stapler die Antworten auf dieses Problem. Ich war gerade dabei, meine Gedanken in einen Kommentar zu diesen zu stecken, aber ich glaube, mein Ansatz ist zu antworthaft, um nicht hier zu bleiben.

Kurz zusammengefasst haben Sie einen Algorithmus identifiziert, mit dem Sie feststellen können, dass ein Coca-Cola-Logo an einer bestimmten Stelle im Raum vorhanden ist. Sie versuchen nun, für beliebige Orientierungen und willkürliche Skalierungsfaktoren eine Heuristik zu finden, die geeignet ist, Coca-Cola- Dosen von anderen Objekten zu unterscheiden, einschließlich: Flaschen , Werbetafeln , Werbungen und Coca-Cola-Utensilien, die alle mit diesem ikonischen Logo verbunden sind. Sie haben nicht viele dieser zusätzlichen Fälle in Ihrer Problembeschreibung genannt, aber ich denke, sie sind entscheidend für den Erfolg Ihres Algorithmus.

Das Geheimnis besteht hier darin, zu bestimmen, welche visuellen Merkmale eine Dose enthält, oder durch den negativen Raum, welche Merkmale für andere Coke-Produkte vorhanden sind, die für Dosen nicht vorhanden sind. Zu diesem Zweck skizziert die aktuelle Top-Antwort einen grundlegenden Ansatz für die Auswahl von "kann", wenn und nur wenn "Flasche" nicht identifiziert wird, entweder durch das Vorhandensein einer Flaschendeckel, Flüssigkeit oder andere ähnliche visuelle Heuristiken.

Das Problem ist, dass dies zusammenbricht. Eine Flasche könnte beispielsweise leer sein und keine Kappe aufweisen, was zu einem falschen Positiv führt. Oder es könnte eine teilweise Flasche mit zusätzlichen Funktionen gemangelt werden, was wiederum zu einer falschen Erkennung führt. Es ist unnötig zu sagen, dass dies weder elegant ist, noch für unsere Zwecke effektiv ist.

Zu diesem Zweck scheinen die richtigsten Auswahlkriterien für Dosen folgende zu sein:

  • Ist die Form der Objekt-Silhouette, wie Sie in Ihrer Frage skizziert haben , korrekt? Wenn ja, +1.
  • Wenn wir annehmen, dass natürliches oder künstliches Licht vorhanden ist, erkennen wir einen Chromumriss an der Flasche, der anzeigt, ob dieser aus Aluminium besteht? Wenn ja, +1.
  • Stellen wir fest, dass die Spiegeleigenschaften des Objekts im Verhältnis zu unseren Lichtquellen korrekt sind ( illustrativer Video-Link zur Lichtquellenerkennung )? Wenn ja, +1.
  • Können wir andere Eigenschaften über das Objekt bestimmen, die es als eine Dose identifizieren, einschließlich, aber nicht beschränkt auf die topologische Bildschrägstellung des Logos, die Ausrichtung des Objekts, die Gegenüberstellung des Objekts (z. B. auf einer ebenen Oberfläche) wie ein Tisch oder im Zusammenhang mit anderen Dosen), und das Vorhandensein einer Zuglasche? Wenn ja, für jeden, +1.

Ihre Klassifizierung könnte dann wie folgt aussehen:

  • Wenn bei jedem Kandidatenmatch ein Coca-Cola-Logo erkannt wurde, zeichnen Sie eine graue Umrandung.
  • Zeichnen Sie für jedes Match über +2 einen roten Rahmen.

Dies hebt den Benutzer visuell hervor, was entdeckt wurde, und hebt schwache Positive hervor, die korrekt als verstümmelte Dosen erkannt werden können.

Die Erkennung jeder Eigenschaft hat eine sehr unterschiedliche Zeit- und Raumkomplexität, und für jeden Ansatz ist ein schneller Durchlauf durch http://dsp.stackexchange.com mehr als sinnvoll, um den für Ihre Zwecke am besten geeigneten und effizientesten Algorithmus zu ermitteln. Meine Absicht hier ist, rein und einfach zu betonen, dass das Erkennen, ob etwas eine Dose ist, indem ein kleiner Teil des Kandidatenerkennungsraums ungültig gemacht wird, nicht die robusteste oder effektivste Lösung für dieses Problem ist, und idealerweise sollten Sie die geeigneten Maßnahmen ergreifen entsprechend.

Und hey, herzlichen Glückwunsch zum Hacker-News-Posting! Im Großen und Ganzen ist dies eine ziemlich grandiose Frage, die der Bekanntheit würdig ist. :)


Um die Dinge zu beschleunigen, würde ich die Tatsache nutzen, dass Sie nicht nach einem beliebigen Bild / Objekt gefragt werden, sondern speziell nach dem Coca-Cola-Logo. Dies ist von Bedeutung, da dieses Logo sehr markant ist und eine charakteristische, skaleninvariante Signatur im Frequenzbereich, insbesondere im roten Kanal von RGB, aufweisen sollte. Das heißt, das abwechselnde Rot-zu-Weiß-zu-Rot-Muster, das von einer horizontalen Abtastzeile (die auf einem horizontal ausgerichteten Logo trainiert wird) getroffen wird, wird einen charakteristischen "Rhythmus" haben, wenn es durch die zentrale Achse des Logos verläuft. Dieser Rhythmus wird bei verschiedenen Maßstäben und Orientierungen "beschleunigt" oder "verlangsamt", bleibt aber proportional gleich. Sie konnten ein paar Dutzend solcher Scanlinien identifizieren und definieren, sowohl horizontal als auch vertikal durch das Logo und einige weitere diagonal in einem Starburst-Muster. Nennen Sie diese die "Signatur-Scan-Linien".

Die Suche nach dieser Signatur im Zielbild erfolgt einfach durch Scannen des Bildes in horizontalen Streifen. Suchen Sie im roten Kanal nach einer Hochfrequenz (die anzeigt, dass Sie von einer roten in eine weiße Region wechseln). Wenn Sie einmal gefunden haben, prüfen Sie, ob einer der in der Trainingseinheit identifizierten Frequenzrhythmen folgt. Sobald eine Übereinstimmung gefunden wurde, werden Sie sofort die Ausrichtung und Position der Scanlinie im Logo kennen (wenn Sie diese Dinge während des Trainings verfolgen), so dass die Grenzen des Logos von dort aus trivial sind.

Ich wäre überrascht, wenn dies kein linear effizienter Algorithmus wäre. Es geht offensichtlich nicht um Ihre Dosenflaschen-Diskriminierung, aber zumindest werden Sie Ihre Logos haben.

(Update: Für die Flaschenerkennung würde ich nach Koks (die braune Flüssigkeit) neben dem Logo - also in der Flasche - suchen, oder, im Falle einer leeren Flasche, würde ich nach einer Kappe suchen , die immer die hat gleiche Grundform, Größe und Abstand vom Logo und werden in der Regel alle weiß oder rot. Suche nach einer soliden Farbe elliptische Form, wo eine Kappe sollte relativ zum Logo sein.Nicht idiotensicher natürlich, aber Ihr Ziel sollte hier sein finde die einfachen schnell .)

(Es sind ein paar Jahre seit meinen Tagen der Bildverarbeitung vergangen, daher habe ich diesen Vorschlag auf hohem Niveau und konzeptionell gehalten. Ich denke, er könnte sich leicht annähern, wie ein menschliches Auge operieren könnte - oder zumindest wie mein Gehirn funktioniert!)


Ist es nicht einmal für den Menschen schwierig, im zweiten Bild zwischen einer Flasche und einer Dose zu unterscheiden (vorausgesetzt, der transparente Bereich der Flasche ist verdeckt)?

Sie sind fast gleich, abgesehen von einem sehr kleinen Bereich (das heißt, die Breite oben auf der Dose ist ein wenig klein, während die Umhüllung der Flasche überall die gleiche Breite hat, aber eine kleine Änderung, richtig?).

Das erste, was mir in den Sinn kam, war, nach der roten Flasche zu suchen. Aber es ist immer noch ein Problem, wenn es kein Oberteil für die Flasche gibt, oder wenn es teilweise versteckt ist (wie oben erwähnt).

Das zweite, was ich dachte, war die Transparenz der Flasche. OpenCV hat einige Arbeiten, um transparente Objekte in einem Bild zu finden. Überprüfen Sie die folgenden Links.

Schauen Sie sich insbesondere an, wie genau sie Glas erkennen:

Sehen Sie ihr Implementationsergebnis:

Sie sagen, es ist die Umsetzung des Papiers "A Geodesic Active Contour Framework for Finding Glass" by K. McHenry and J. Ponce, CVPR 2006. . (Download Papier) .

Es könnte in Ihrem Fall ein wenig hilfreich sein, aber das Problem tritt wieder auf, wenn die Flasche gefüllt ist.

Ich denke also, hier können Sie zuerst nach dem transparenten Körper der Flaschen suchen oder nach einem roten Bereich, der seitlich mit zwei transparenten Objekten verbunden ist, was offensichtlich die Flasche ist. (Wenn Sie im Idealfall arbeiten, ein Bild wie folgt.)

Jetzt können Sie den gelben Bereich, also die Beschriftung der Flasche, entfernen und Ihren Algorithmus ausführen, um die Dose zu finden.

Wie auch immer, diese Lösung hat auch andere Probleme als bei den anderen Lösungen.

  1. Es funktioniert nur, wenn Ihre Flasche leer ist. In diesem Fall müssen Sie nach dem roten Bereich zwischen den beiden schwarzen Farben suchen (wenn die Coca-Cola-Flüssigkeit schwarz ist).
  2. Ein weiteres Problem, wenn das transparente Teil abgedeckt ist.

Aber wenn es keines der oben genannten Probleme in den Bildern gibt, scheint dies zu einem besseren Weg zu sein.


The first things I would look for are color - like RED , when doing Red eye detection in an image - there is a certain color range to detect , some characteristics about it considering the surrounding area and such as distance apart from the other eye if it is indeed visible in the image.

1: First characteristic is color and Red is very dominant. After detecting the Coca Cola Red there are several items of interest 1A: How big is this red area (is it of sufficient quantity to make a determination of a true can or not - 10 pixels is probably not enough), 1B: Does it contain the color of the Label - "Coca-Cola" or wave. 1B1: Is there enough to consider a high probability that it is a label.

Item 1 is kind of a short cut - pre-process if that doe snot exist in the image - move on.

So if that is the case I can then utilize that segment of my image and start looking more zoom out of the area in question a little bit - basically look at the surrounding region / edges...

2: Given the above image area ID'd in 1 - verify the surrounding points [edges] of the item in question. A: Is there what appears to be a can top or bottom - silver? B: A bottle might appear transparent , but so might a glass table - so is there a glass table/shelf or a transparent area - if so there are multiple possible out comes. A Bottle MIGHT have a red cap, it might not, but it should have either the shape of the bottle top / thread screws, or a cap. C: Even if this fails A and B it still can be a can - partial.. This is more complex when it is partial because a partial bottle / partial can might look the same , so some more processing of measurement of the Red region edge to edge.. small bottle might be similar in size ..

3: Nach der obigen Analyse würde ich dann den Schriftzug und das Wellenlogo betrachten - weil ich meine Suche nach einigen der Buchstaben in den Wörtern orientieren kann, da Sie vielleicht nicht den ganzen Text haben, weil Sie nicht alle haben Kann die Welle an bestimmten Punkten auf den Text ausgerichtet werden (distanzweise), so könnte ich nach dieser Wahrscheinlichkeit suchen und wissen, welche Buchstaben an diesem Punkt der Welle in Abstand x existieren sollen.


Ein alternativer Ansatz wäre das Extrahieren von Merkmalen (Schlüsselpunkten) unter Verwendung der skaleninvarianten Merkmaltransformation (SIFT) oder der beschleunigten beschleunigten Merkmale (SURF).

Es ist in OpenCV 2.3.1 implementiert.

Sie können ein nettes Codebeispiel mit Features in Features2D + Homography finden, um ein bekanntes Objekt zu finden

Beide Algorithmen sind gegenüber Skalierung und Rotation invariant. Da sie mit Features arbeiten, können Sie auch mit occlusion umgehen (solange genug Keypoints sichtbar sind).

Bildquelle: Tutorial-Beispiel

Die Verarbeitung dauert einige hundert ms für SIFT, SURF ist etwas schneller, aber nicht für Echtzeitanwendungen geeignet. ORB verwendet FAST, was hinsichtlich der Rotationsinvarianz schwächer ist.

Die Original-Papiere


Es gibt ein Computer-Vision-Paket namens HALCON von MVTec, dessen Demos Ihnen gute Algorithmen-Ideen geben könnten. Es gibt viele ähnliche Beispiele für Ihr Problem, die Sie im Demo-Modus ausführen könnten, und dann die Operatoren im Code betrachten und sehen, wie Sie sie von vorhandenen OpenCV-Operatoren implementieren.

Ich habe dieses Paket verwendet, um komplexe Algorithmen für solche Probleme schnell zu entwickeln und dann zu finden, wie man sie unter Verwendung der vorhandenen OpenCV-Funktionen implementiert. Insbesondere könnten Sie in Ihrem Fall versuchen, die in den Operator find_scaled_shape_model eingebettete Funktionalität in OpenCV zu implementieren. Einige Betreiber weisen auf die wissenschaftliche Arbeit zur Implementierung des Algorithmus hin, die helfen könnte, etwas Ähnliches in OpenCV zu finden. Hoffe das hilft...


Ich würde rote Rechtecke erkennen: RGB -> HSV, Filter rot -> binäres Bild, close (dilatieren und erodieren, bekannt als imclose )

Dann durch die Rechtecke vom Größten zum Kleinsten schauen. Rechtecke mit kleineren Rechtecken in einer bekannten Position / Skala können beide entfernt werden (unter der Annahme, dass die Flaschenproportionen konstant sind, wäre das kleinere Rechteck eine Flaschenkapsel).

Das würde Sie mit roten Rechtecken belassen, dann müssen Sie irgendwie die Logos erkennen, um zu sagen, ob sie ein rotes Rechteck oder eine Cola-Dose sind. Wie OCR, aber mit einem bekannten Logo?


Bitte schauen Sie sich den Predator-Tracker von Zdenek Kalal an. Es erfordert etwas Training, aber es kann aktiv lernen, wie das verfolgte Objekt verschiedene Orientierungen und Skalen betrachtet, und zwar in Echtzeit!

Der Quellcode ist auf seiner Website verfügbar. Es ist in MATLAB , aber vielleicht wurde bereits eine Java-Implementierung von einem Community-Mitglied ausgeführt. Ich habe den Tracker-Teil von TLD erfolgreich in C # implementiert. Wenn ich mich richtig erinnere, benutzt TLD Farne als Schlüsselpunktdetektor. Ich benutze entweder SURF oder SIFT stattdessen (bereits von @ Stacker vorgeschlagen), um das Objekt wiederzuerlangen, wenn es vom Tracker verloren gegangen ist. Die Rückmeldung des Trackers macht es einfach, mit der Zeit eine dynamische Liste von Sift / Surf-Vorlagen zu erstellen, die mit der Zeit es ermöglichen, das Objekt mit sehr hoher Genauigkeit wiederzuerlangen.

Wenn Sie an meiner C # -Implementierung des Trackers interessiert sind, zögern Sie nicht zu fragen.


Spaßiges Problem: Als ich auf dein Flaschenbild geschaut habe, dachte ich, es wäre auch eine Dose. Aber als Mensch, was ich getan habe, um den Unterschied zu erkennen, ist mir aufgefallen, dass es auch eine Flasche war ...

Also, um Dosen und Flaschen auseinander zu halten, wie wäre es damit, zuerst nach Flaschen zu suchen? Wenn Sie einen finden, maskieren Sie das Etikett, bevor Sie nach Dosen suchen.

Nicht zu schwer zu implementieren, wenn Sie bereits Dosen tun. Der eigentliche Nachteil ist, dass es Ihre Bearbeitungszeit verdoppelt. (Aber wenn man an reale Anwendungen denkt, wirst du am Ende sowieso Flaschen machen wollen ;-)


Die Antworten auf dieser Seite lauten:

  • "SIFT benutzen"

  • "Verwenden Sie einen Kinect"

Wenn Sie sich nicht für die eigentliche Computerwissenschaft der Bilderkennung interessieren und nur etwas (wie SIFT oder Kinect) "benutzen" wollen,

Es ist heutzutage allgegenwärtig, nur die allgemein verfügbaren Bilderkennungssysteme zu verwenden.

Ab 2017 und seit Jahren ist die Bilderkennung weit und trivial verfügbar .

Sie würden sich nicht mehr hinsetzen und versuchen, die Bilderkennung von Grund auf neu zu erstellen, als wenn Sie sich hinsetzen und anfangen, Karten zu sammeln und anzuzeigen, oder HTML von Grund auf neu zu erstellen oder eine SQL-Datenbank von Grund auf neu zu schreiben.

Sie verwenden einfach den Tensorflow von Google (sie haben den Punkt erreicht, Chips zu bauen, um den Tensorfluss schneller zu verarbeiten), Clarifai, Bluemix oder was auch immer.

AWS hat gerade eine gute Bilderkennung (2018) veröffentlicht.

Um zum Beispiel einen dieser Dienste zu benutzen, sind es ein paar Zeilen Code ....

func isItACokeCan() {

    jds.headers = ["Accept-Language":"en"]
    let h = JustOf<HTTP> ...use your favorite http library

    let u: String =
        "https://gateway-a.watsonplatform.net/visual-recognition/api/v3/classify"
        + "?api_key= ... your API key ..."
        + "&version=2016-05-20"
        + "&classifier_ids= ... your Classifier name ..."

    h.post( u,
        files: ["x.jpeg": .data("x.jpeg", liveImageData!, "image/jpeg")]

    ) { r in
        if r.ok { DispatchQueue.main.async { self.processResult(r.json) } }
        else { DispatchQueue.main.async { self.doResults("network woe?") } }
    }
}

func processResult(_ rr: Any?){
    let json = JSON(rr!)
    print("\(json)")
}

Das wird Ihnen im wahrsten Sinne des Wortes die beste existierende Koks-Dosen-Erkennung auf der Erde geben .

Ab 2018 kann man sich nicht mehr hinsetzen und "bessere Cola-Dosen-Erkennung als Bluemix schreiben", als wenn man sich "hinsetzen und ein besseres Go-Programm schreiben könnte als AlphaGo".

Systeme wie Siri, Google Maps, BAAS, die großen Bildverarbeitungsbemühungen - und natürlich die Google-Textsuche selbst - sind bahnbrechend.

Beachten Sie den unglaublichen Unterschied, seit diese Frage vor sechs Jahren gestellt wurde.

Auf jeden Fall, wenn Sie in der eigentlichen Computerwissenschaft der Bilderkennung sind , gehen Sie dafür.

Aber diese QA scheint eher eine Überprüfung der Technologie zu sein.

Insofern die Antworten hier lauten: "Benutze eine SIFT-Bibliothek" - das würdest du wirklich nicht tun. (Noch einmal - nicht mehr als Sie aus irgendeinem Grund mühevoll einen Webserver oder eine SQL-Datenbank von Grund auf neu programmieren!)

Sie verbinden sich einfach mit den bekannten, allgegenwärtigen "BAAS" -Systemen zur Bilderkennung - das ist eine Codezeile.


Ich mag die Herausforderung und wollte eine Antwort geben, die das Problem löst, denke ich.

  1. Extrahieren Sie Features (Schlüsselpunkte, Deskriptoren wie SIFT, SURF) des Logos
  2. Passe die Punkte mit einem Modellbild des Logos an (mit Matcher wie Brute Force)
  3. Schätzen Sie die Koordinaten des starren Körpers ab (PnP-Problem - SolvePnP)
  4. Schätzen Sie die Kappenposition nach dem starren Körper
  5. Projizieren Sie Rückprojektion und berechnen Sie die Bildpixelposition (ROI) des Flaschenverschlusses (ich nehme an, Sie haben die intrinsischen Parameter der Kamera)
  6. Überprüfen Sie mit einer Methode, ob die Kappe vorhanden ist oder nicht. Wenn da, dann ist das die Flasche

Die Erkennung der Kappe ist ein anderes Problem. Es kann entweder kompliziert oder einfach sein. Wenn ich Sie wäre, würde ich einfach das Farbhistogramm in der ROI für eine einfache Entscheidung überprüfen.

Bitte geben Sie das Feedback, wenn ich falsch liege. Vielen Dank.


Ich denke, alle stimmen zu, dass es eine andere Art geben sollte, das zu tun, was Sie tun möchten. Das Kompilieren von Hunderten von Megabyte (Gigabyte) an Code, Verknüpfen in eine ausführbare Datei mit mehreren Gigabyte und das Ausführen von Code klingt einfach sehr ineffizient.

Wenn ich Ihr Problem richtig verstehe, verwenden Sie eine Art von Code-Generator, G, um eine Reihe von Funktionen func1...N zu generieren, die eine Reihe von Karten csc1...M als Eingabe csc1...M . Was Sie tun möchten, ist csc1...M berechnet, und eine Schleife von 1.000.000 Mal für verschiedene Eingaben und jedes Mal finden Sie s = func1 + func2 + ... + funcN . Sie haben nicht angegeben, wie fucn1...N mit csc1...M verwandt ist.

Wenn alles wahr ist, scheint es, dass Sie in der Lage sein sollten, das Problem auf eine andere Art und Weise auf den Kopf zu stellen, die möglicherweise viel überschaubarer und möglicherweise sogar schneller ist (dh den Cache Ihres Rechners tatsächlich funktionieren lässt).

Neben dem praktischen Problem der Größe der Objektdateien ist Ihr aktuelles Programm nicht effizient, da es den Zugriff auf die Daten nicht lokalisiert (zu viele große Maps) und keine lokalisierte Codeausführung (zu viele sehr lange Funktionen) hat.

Wie wäre es, csc1...M Ihr Programm in 3 Phasen csc1...M : Phase 1 baut csc1...M und speichert sie. In Phase 2 wird jeweils eine Funktion erstellt, bei jeder Eingabe 1.000.000 Mal ausgeführt und die Ergebnisse gespeichert. Phase 3 ermittelt die Summe der Ergebnisse der gespeicherten func1...N Ergebnisse für jeden Lauf von 1.000.000 Mal. Der gute Teil dieser Lösung ist, dass sie leicht parallel zu mehreren unabhängigen Maschinen erstellt werden kann.

Edit: @bbtrb, könntest du einen func und einen csc zur Verfügung stellen? Sie scheinen sehr regelmäßig und komprimierbar zu sein. Zum Beispiel scheint func1 nur eine Summe von Ausdrücken zu sein, die jeweils aus einem Koeffizienten, zwei Indizes für die Variablen in s und einem Index in csc bestehen. So kann es zu einer schönen Schleife reduziert werden. Wenn Sie vollständige Beispiele zur Verfügung stellen, bin ich mir sicher, dass Wege gefunden werden können, sie in Schleifen anstatt in lange Ausdrücke zu komprimieren.





c++ algorithm image-processing opencv