Bestimmen Sie, ob ein Bild vorhanden ist, in einem größeren Bild, und wenn dem so ist, finden es, mit Python
Brauche ich ein Python-Programm, dass ich arbeite, um in der Lage sein zu nehmen, ein kleines Bild, bestimmt, wenn es existiert, in einem größeren Bild, und wenn dem so ist, meldet seine Position. Wenn nicht, melden, die. (In meinem Fall das große Bild wird ein screenshot, und das kleine Bild ein Bild, das möglicherweise oder möglicherweise nicht auf dem Bildschirm, die in einem HTML5-canvas.) Suchen Sie on-line, fand ich heraus, über template-matching in OpenCV, die in der Tat hervorragende Python-bindings. Ich habe versucht, die folgenden, basierend auf sehr ähnlichen code, den ich gefunden auf Linie mit numpy sowie:
import cv2
import numpy as np
image = cv2.imread("screenshot.png")
template = cv2.imread("button.png")
result = cv2.matchTemplate(image,template,cv2.TM_CCOEFF_NORMED)
StartButtonLocation = np.unravel_index(result.argmax(),result.shape)
Dieser nicht tut, was ich brauche, es zu tun, denn es gibt IMMER einen Punkt in dem größeren Bild, dem Punkt, wo das Spiel am nächsten ist, egal wie schrecklich ein Spiel es ist. Ich etwas will, der findet eine genaue, pixel für pixel entsprechen, der das kleinere Bild im größeren Bild, und wenn keiner vorhanden ist, wirft Sie eine Ausnahme, oder gibt False
oder sowas. Und es muss Recht schnell erfolgen. Hat jemand eine gute Idee, wie dies zu tun?
- Eine kurze Frage: kann man davon ausgehen, dass Ihre
small
Bild erscheint in derlarge
Bild immer in Originalgröße und genau mit Ihrem original-Werte? Oder müssen Sie den Umgang mit Variablen Größesmall
Bilder, die möglicherweiseinterpolated
und Griffillumination
- Variationen? Ich meine, Sie erwähnenexact match
ist es wirklich genau? - Sind Sie garantiert IMMER
PNG
format? Ich Frage beauseJPEG
s Unterziehen Quantisierung verlustfreie Kompression und verlustbehaftete Kompression und Dinge, die scheinbar identisch können unterscheiden sich in Ihrer internen Darstellung.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Werde ich vorschlagen, eine Antwort, die funktioniert schnell und perfekt, wenn Sie suchen für
exact match
sowohl in Größe und in der image-Werte.Die Idee ist die Berechnung eines brute-force-Suche von das wollte
h x w
Vorlage in einem größerenH x W
Bild. Der bruteforce-Ansatz würde darin bestehen, sich auf alle möglichenh x w
windows über das Bild und überprüfen Sie die pixel-by-pixel-Korrespondenz innerhalb der Vorlage. Dieses ist jedoch sehr rechenintensiv, kann aber beschleunigt werden.Mithilfe der smart integral-Bilder man berechnen kann wirklich schnell die Summe innerhalb eines
h x w
Fenster, beginnend an jedem pixel. Ein integraler Bild ist ein kombiniertes Bereich Tabelle (kumulativ summiert array) berechnet werden kann, mit numpy wirklich schnell:und es hat wirklich schöne Eigenschaften, wie zum Beispiel die Berechnung der Summe aller Werte in einem Fenster mit nur 4 arithmetische Operationen:
So, durch die Berechnung der Summe der Vorlage und Abgleich mit der Summe der
h x w
windows über die integrierte Bild, es ist leicht zu finden, eine Liste von "möglichen windows", wo die Summe der inneren Werte ist die gleiche wie die Summe der Werte in der Vorlage (eine schnelle Annäherung).Oben ist ein numpy Vektorisierung der Betrieb der in der Abbildung für alle möglichen
h x w
Rechtecke auf dem Bild (also wirklich schnell).Dies verringert eine Menge der Anzahl der möglichen Fenster (2 in einem meiner tests). Der Letzte Schritt wäre zu prüfen, wird nach exakten übereinstimmungen mit der Vorlage:
Beachten Sie, dass hier
y
undx
Koordinaten beziehen sich auf den Einen Punkt im Bild, wird die vorhergehende Zeile und Spalte der Vorlage.Setzen alle zusammen:
Funktioniert es mit beiden Graustufen-und Farbbilder und läuft in
7ms
für eine303x384
Farb-Bild mit einem50x50
Vorlage.Einem Beispiel aus der Praxis:
Und ilustrate das Ergebnis:
Links Originalbild, rechts die Vorlage. Und hier die genaue übereinstimmung:
Und letzten, nur ein Beispiel für die
possible_matches
für den test:Die Summe über die beiden Fenster im Bild ist die gleiche, aber der Letzte Schritt der Funktion Filter, die nicht exakt der Vorlage.
np.logical_and(*[...])
- erwarten Sienp.logical_and
zu nehmen, eine beliebige Anzahl von Dingen zu UND gemeinsam? NumPy ufuncs nicht so funktioniert. Bist du eigentlich angeben das Dritte element in der Liste als array an Stelle der Ausgabe, und nicht als ein array auf UND zusammen. Die ufuncreduce
- Methode könnte helfen:np.logical_and.reduce([...])
(keine*
) stattnp.logical_and(*[...])
.x
odery
0 ist. Die einzige Lösung, die ich mir ausgedacht habe, denn es ist ziemlich hacky: Verwenden Siecv2
erstellen einen 1px Rand entlang der oberen und linken Ränder des haystack-Bild, bevor der Suche nach der Nadel.img = np.pad(img, ((1,0), (1,0), (0,0)), mode='constant')
(Syntax vielleicht ein wenig off, Im von Handy und kippe es zu überprüfen). Aber danke für das lassen Sie mich wissen! Ist ein schnelles und schönes Update 🙂Da Sie sind zufrieden mit OpenCV, ich würde vorschlagen, dass Sie beginnen mit dem, was Sie bereits getan haben, und Holen Sie sich die besten match. Sobald Sie die Lage des best match, können Sie überprüfen, dass es tatsächlich ein gutes Spiel.
Überprüfen, dass es ist ein gutes Spiel sollte so einfach wie extrahieren der passenden Bild und dem Vergleich mit der Vorlage. Extrahieren Sie das Bild, das Sie möglicherweise verwenden müssen
cv2.minMaxLoc(result)
- und Prozess-Ausgang. Die Extraktion-Methode scheint davon abzuhängen, wie die verwendete Methode für den Vergleich der Bilder und ist fertig mit Beispiele hier.Sobald Sie extrahiert haben, das Bild, Sie sollte in der Lage sein, Sie zu vergleichen mit
numpy.allclose
oder eine andere Methode.