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.
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?
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.
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.
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.
Nein, der Marker bleibt von der Größe und Farbe immer gleich, dass macht es etwas leichter.
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?
Template matching. Damit berechnest du einen Score, und der sollte dann bei kompletter Uebereinstimmung deutlich hoeher sein als bei irgendwelchen random red pixels.
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?
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...
# 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
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.
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?
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