OpenCV Tracken eines Markers

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

Guten Abend,

im Bild kann man einen roten, drachenförmigen Marker erkennen, der gegnerische Feinde hervorhebt.

Ja, ein ähnliches Thema wurde in einer meiner Threads bereits besprochen^^
Allerdings funzt Tensorflow bzw Keras auf meinem alten PC nicht, aber bald kommt was neues. xd

Das Tracken erfolgt über ein ColorTracker (BGR Farbbereich), der zur Unterstützung Konturen verwendet, um so kleine Pixelhaufen zu vermeiden.
Mein Problem ist, dass es dennoch teils Mal andere Pixel als Marker erkennt - ist ja klar, es trackt einfach das größte Objekt und manchmal sind auch andere Objekte im vorgegebenen Farbbereich.
Außerdem wird der Marker nicht komplett an der Stelle getrackt, an der sich dieser eigentlich befindet. Zoome ich im Bild herran (zum Testen lasse ich den Algorithmus über ein Testbild laufen), dann wird der Marker immer genauer getrackt.
(Mit "cv2.putText()" lasse ich mir den getrackten Bereich über "imshow()" anzeigen.)

Daher frage ich mich wie man den Tracker verbessern kann, geschweige denn, warum das mit dem Bild herranzoomen so ist?


Bild

Grüße,
xXSkyWalkerXx1
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du trackst ja nicht. Du suchst einfach nur jedes mal.

Echtes Tracking bedeutet, dass man ein einmal gefundenes Objekt respektive dessen Zustand (bei dir also X/Y-Koordinate) durch neue Informationen zu updaten. Statt jedes mal neu zu suchen. Dazu kann man im simpelsten Fall einfach nur einen Suchradius um die letzte bekannte Position herum definieren. Da die eigene Spielerbewegung da auch ins Spiel kommt, kannst du auch versuchen die einfliessen zu lassen, um den Suchbereich zu beeinflussen. ZB mit einer optischen Fluss Berechnung. Das geht eigentlich recht schnell, und sollte sich auch auf einem kleiner skalierten Bild machen lassen. Damit kannst du dann die Suchregion um die Richtung des Flusses verschieben.

Deine Bemerkung bezueglich der Position verstehe ich nicht.
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

Stimmt. ^^

Ich lasse meinen Algorithmus über einen ROI laufen, also einen Radius, um die Performance zu erhöhen und da, z.b. die Minimap auch rot ist (aber auch wegen anderen Dingen), Probleme zu vermeiden.

Zur Anmerkung:
Man sieht ja den roten Marker im Bot. Zum Testen lasse ich für jeden "getrackten" Pixel einen "*" setzen. Somit bildet dieser den Rahmen des Markers.
Allerdings ist er etwas in Richtung 45° verschoben, wenn ich aber im Bild ranzoome und die Pixel größer werden, liegt er genau auf dem Marker.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das klingt für mich jetzt eher danach, dass Text Rendering nicht so gelungen ist für das präzise markieren von Dingen.
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

Was meinst du mit Text-Rendering?
Es wird jeweils nur auf den Marker gesetzt, nicht auf den roten Namenstext.

Wäre in meinem Fall eigentlich ein anderer Farbraum besser?
Also statt BGR HSV?
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du redest davon, das du * benutzt, um etwas zu markieren. Fuer mich ist * ein Zeichen, das man mit einer Text-Rendering-Funktion erzeugt. Und damit ist es nicht praezise auf eine Koordinate zu legen (jedenfalls nicht so ohne weiteres).

Und was den Farbraum angeht: ich denke nicht. Normalerweise ja, aber da dein Problem anders als mit Videos aus der echten Welt nicht mit Beleuchtungsproblemen zu kaempfen hat, ist der praezise RGB-Wert genauso gut. Es bringt dir ueberhautp nichts, durch HSV jetzt noch irgendwelche anderen ungefaehr-auch-roten Bereiche zu entdecken. Nur wenn meine Vermutung hier nicht stimmt, und der Marker seine Faerbung aendert, waere das *vielleicht* zu erwaegen.
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

Achsoo...Ja, stimmt, könnte auch sein.

Nein, der Marker bleibt von der Größe und Farbe immer gleich, dass macht es etwas leichter. :D
Dann versuche ich erstmal das Filtering zu verbessern, damit der Algorithmus auch hauptsächlich nur auf (bzw. unter) dem Marker zielt.
Noch Ideen bzw Tipps, damit dieser den Marker besser erkennt und andere Objekte der ähnlichen Farbe ausblendet?
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Template matching. Damit berechnest du einen Score, und der sollte dann bei kompletter Uebereinstimmung deutlich hoeher sein als bei irgendwelchen random red pixels.
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

Bin deinen Gedanken Mal nachgegangen, wegen Text-Rendering.
Habe nun die Funktion "cv2.drawContures()" verwendet und der "Fehler" war behoben.

Okay, danke...ich schaue Mal nach genaueres zu "Template matching".
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

Wie lassen sich die unterschiedlichen Methoden für "cv2.matchTemplate()" erklären - also worin liegt der Unterschied?
Es stehen nur Formeln da, die mir jetzt auch nicht viel sagen. ^^

Mit welchem Tool kann ich eigentlich so genau wie möglich den Marker aus dem Bild oben ausschneiden und als PNG speichern?
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

Links seht ihr den originalen Marker, rechts den kopierten (mit GIMP).

Mein Algorithmus verwendet nun den kopierten Marker als Template.
Problem ist, dass "cv2.matchTemplates()" den Marker nicht findet, obwohl der kopierte doch fast identisch dem originalen ist...

Code: Alles auswählen

# Search enemy with template.
match_temp = cv2.matchTemplate(
	window,
	enemy_marker,
	cv2.TM_CCOEFF_NORMED)
min_val, max_val, min_locat, max_locat = cv2.minMaxLoc(match_temp)
print(max_val) # Immer nur zwischen 0.05 und 0.2
Bild
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ich würde das Template matching nur zur verifikation nutzen. Also bei schon bekannten Kandidaten durch Tracking.
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

Verstehe gerade nicht wie du das genau meinst? ...inwiefern denn "bekannte Kandidaten"?
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Wie zu beginn geschrieben, *tracking*. Also eine Hypothese bilden, wo der Tracker im naechsten Bild ist. Da nach roten Flecken suchen. Und dann einen match berechnen. Aber eigentlich ist das Unsinn, was ich da vorgeschlagen habe. Du musst ja auch den Fall abdecken, dass ein Marker erst ins Bild kommt.

Fuer einen besseren matching-Score solltest du natuerlich das Bild so modifizieren, dass nur die relevanten roten Pixel da sind, und der Rest schwarz. Und dein Template muss genauso aussehen. Sonst kommen natuerlich die umliegenden Pixel unvorhersehbar in die Bewertung mit rein, und koennen das Ergebnis mindestens mal verschieben.
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

Ja, naja, es lässt sich ja schlecht ableiten, wo sich der Gegner in der nächsten Sekunde befindet... :D

Also eine Maske bilden, mit Lower & Upper RGB Werten, mit dem Originalbild vergleichen, Template-Detektor drüber laufen lassen und "fertig"...
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

So siehts nun aus:
Bild

Als Position gibt es mir allerdings eine merkwürdige aus.
Kann es sein, dass der 0-Punkt nicht mehr vom Bildschirm bestimmt ist, sondern aus der Maske?

Allerdings ist auch der Score noch recht gering.
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

Es scheint sogar sehr gut zu funktionieren! :)
Muss nur noch schauen, wie ich die Performance erhöhe, da ich einen ~8J. alten, miesen Desktop-PC habe und das Template-Matching allein 400ms beansprucht. xd
Antworten