opencv Foundation 57-Vorlage passend zu cv2.matchTemplate()->(Zielerkennung, Bilderkennung, Merkmalsextraktion)

OpenCV bietet die Funktion des Vorlagenabgleichs (Template Matching), mit der Sie die passende Position einer bestimmten Vorlage (kleines Bild) im Zielbild im Bild finden können. Der Vorlagenabgleich wird in der Computer Vision zur Objekterkennung, Bilderkennung, Merkmalsextraktion und anderen Bereichen verwendet.

Im Folgenden sind die grundlegenden Schritte zur Verwendung des Vorlagenabgleichs in OpenCV aufgeführt:

  1. Bilder laden : Laden Sie zunächst das Zielbild und das entsprechende Vorlagenbild.

  2. Wählen Sie die passende Methode aus : Wählen Sie die entsprechende passende Methode aus, z. B. cv2.TM_CCOEFF, cv2.TM_CCOEFF_NORMED, cv2.TM_CCORR, cv2.TM_CCORR_NORMED, cv2.TM_SQDIFF oder cv2.TM_SQDIFF_NORMED. Jede Methode entspricht einer anderen Matching-Berechnungsmethode.

  3. Anwenden des Vorlagenabgleichs : Verwenden Sie für den Vorlagenabgleich die Funktion cv2.matchTemplate(), die eine Matrix mit Übereinstimmungsergebnissen zurückgibt.

  4. Finden Sie die beste Übereinstimmungsposition : Finden Sie in der Übereinstimmungsergebnismatrix die beste Übereinstimmungsposition, indem Sie die Pixelwerte analysieren, dh die Übereinstimmungsposition im Zielbild.

Beim Vorlagenabgleich geht es darum, den Teil im aktuellen Bild A zu finden, der Bild B am ähnlichsten ist. Im Allgemeinen wird Bild A als Eingabebild und Bild B als Vorlagenbild bezeichnet. Die Operationsmethode des Vorlagenabgleichs besteht darin, das Vorlagenbild B auf dem Bild A zu verschieben und alle Pixel zu durchlaufen, um den Abgleich abzuschließen.

In Abbildung 15-1 möchten Sie beispielsweise das „Auge“-Bild in der oberen linken Ecke innerhalb des großen Bildes „Lena“ in der Abbildung finden. Zu diesem Zeitpunkt ist das große Bild „lena“ das Eingabebild und das „eye“-Bild das Vorlagenbild. Die Suchmethode besteht darin, das Vorlagenbild von der oberen linken Ecke im Eingabebild zu verschieben und das gesamte Eingabebild Pixel für Pixel zu durchsuchen, um den Teil zu finden, der am besten dazu passt.

Fügen Sie hier eine Bildbeschreibung ein

Beschreibung der Template-Matching-Funktion

In OpenCV wird der Vorlagenabgleich mithilfe der Funktion cv2.matchTemplate() implementiert. Die Syntax dieser Funktion lautet:

result = cv2.matchTemplate(image, templ, method[, mask ] )

In:

  • image ist das Originalbild, das ein 8-Bit- oder 32-Bit-Gleitkommabild sein muss.
  • templ ist das Vorlagenbild. Es muss kleiner oder gleich groß sein und vom gleichen Typ wie das Originalbild sein
    .
  • Methode ist die Matching-Methode. Dieser Parameter wird durch TemplateMatchModes realisiert und es gibt 6 mögliche Werte, wie in Tabelle 15-1 gezeigt.

Fügen Sie hier eine Bildbeschreibung ein

  • mask ist die Bildmaske der Vorlage. Es muss denselben Typ und dieselbe Größe wie das Vorlagenbild templ haben. Normalerweise kann dieser Wert den Standardwert verwenden. Derzeit werden für diesen Parameter nur zwei Werte TM_SQDIFF und TM_CCORR_NORMED unterstützt.

Das Rückgabewertergebnis der Funktion cv2.matchTemplate() ist eine Ergebnismenge, die durch die Kombination der Vergleichsergebnisse jeder Position gebildet wird, und der Typ ist ein einkanaliger 32-Bit-Gleitkommatyp. Wenn die Größe des Eingabebildes (Originalbild) W H und die Größe der Vorlage W H ist,
beträgt die Größe des zurückgegebenen Werts (W-w+1)*(H-h+1).
Beim Vorlagenabgleich werden Vorlagen innerhalb des Originalbilds durchlaufen. In horizontaler Richtung:
I repräsentiert das Eingabebild, T repräsentiert die Vorlage, R repräsentiert das Ausgabeergebnisbild und x und y repräsentieren die Positionsinformationen.

  • Die Startkoordinate der Durchquerung ist der erste Pixelwert von links im Originalbild (die Seriennummer beginnt bei 1).
  • Der letzte Vergleich erfolgt, wenn sich das Vorlagenbild ganz rechts vom Originalbild befindet. Zu diesem Zeitpunkt beträgt die Position des Pixels in der oberen linken Ecke W-w+1.
    Daher beträgt die Größe des Rückgabewertergebnisses in horizontaler Richtung W-w+1 (die Anzahl der Vergleiche in horizontaler Richtung).

In vertikaler Richtung:

  • Die Startkoordinaten der Durchquerung beginnen beim ersten Pixel oben im Originalbild.
  • Der letzte Vergleich erfolgt, wenn sich das Vorlagenbild am unteren Rand des Originalbilds befindet und das Pixel in der oberen linken Ecke bei H-h+1 liegt.

Daher beträgt die Größe des Rückgabewertergebnisses in vertikaler Richtung H-h+1 (die Anzahl der Vergleiche in vertikaler Richtung).
Wenn die Originalbildgröße W H und die Vorlagengröße W H ist, beträgt die Größe des zurückgegebenen Werts (W-w+1) (H-h+1). Das heißt, das Vorlagenbild wird (W-w+1) (H-h+1) Mal innerhalb des Eingabebilds verglichen.

Es ist zu abstrakt . Schauen Sie sich dann die Beschreibung unten an, um zu sehen, ob Sie es besser verstehen können

In Abbildung 15-2 ist beispielsweise das kleine 2×2-Quadrat oben links das Vorlagenbild und das 10×10-Bild unten rechts das Eingabebild
(das Originalbild). Beim Vorlagenabgleich:

  1. Das Vorlagenbild wird zunächst in der oberen linken Ecke des Eingabebildes platziert.
  2. Wenn sich das Vorlagenbild nach rechts bewegt, kann es sich nur am äußersten rechten Rand des Eingabebilds befinden. Zu diesem Zeitpunkt entspricht das Pixel in der oberen linken Ecke des Vorlagenbilds der neunten Spalte des Eingabebilds (Eingabe). Bildbreite - Vorlagenbildbreite + 1 = 10 -2+1 = 9).
  3. Beim Verschieben nach unten kann sich das Vorlagenbild nur am unteren Rand des Eingabebildes befinden. Zu diesem Zeitpunkt entspricht das Pixel in der oberen linken Ecke des Vorlagenbilds der 9. Zeile des Eingabebilds (Höhe des Eingabebilds – Höhe des Vorlagenbilds + 1 = 10-2 + ​​​​1 = 9).
    Aus der obigen Analyse ist ersichtlich, dass die Größe des Vergleichsergebnisses (W-w+1)*(H-h+1) erfüllt, im obigen Beispiel ist sie (10-2+1)× (10-2+1), also 9 × 9. Das heißt, das Vorlagenbild muss im Eingabebild insgesamt 9 × 9 = 81 Mal verglichen werden, und diese Vergleichsergebnisse bilden ein zweidimensionales 9 × 9-Array.

Fügen Sie hier eine Bildbeschreibung ein
Das fühlt sich ein wenig verständnisvoll an.

Hier ist erforderlich, 注意dass cv2.matchTemplate()通过参数 method 来决定使用不同的查找方法。das Rückgabewertergebnis der Funktion für verschiedene Suchmethoden unterschiedliche Bedeutungen hat.

Zum Beispiel:

  • Wenn der Wert der Methode cv2.TM_SQDIFF und cv2.TM_SQDIFF_NORMED ist, ist der Ergebniswert 0, was
    den besten Übereinstimmungsgrad angibt. Je größer der Wert, desto schlechter ist der Übereinstimmungsgrad.
  • Wenn der Wert der Methode cv2.TM_CCORR, cv2.TM_CCORR_NORMED, cv2.TM_CCOEFF und
    cv2.TM_CCOEFF_NORMED ist, gilt: Je kleiner der Ergebniswert, desto schlechter ist der Übereinstimmungsgrad, und je größer der Ergebniswert, desto besser ist der Übereinstimmungsgrad.

Aus der obigen Analyse ist ersichtlich, dass unterschiedliche Suchmethoden zu unterschiedlichen Beurteilungsmethoden für die Ergebnisse führen. Wenn Sie die beste Übereinstimmung finden, bestimmen Sie zunächst, welche Methode verwendet wird, und bestimmen Sie dann, ob der Maximalwert oder der Minimalwert ermittelt werden soll.

Codebeispiel: Verwenden Sie die Funktion cv2.matchTemplate() für den Vorlagenabgleich.

Es ist erforderlich, dass der Wert der Parametermethode auf cv2.TM_SQDIFF gesetzt wird, um das Rückgabeergebnis und das übereinstimmende Ergebnis der Funktion anzuzeigen.

Suchen Sie zunächst im Internet nach einem Bild, schneiden Sie dann einen Teil des Bildes aus und speichern Sie es als Bild.

Fügen Sie hier eine Bildbeschreibung ein

Fügen Sie hier eine Bildbeschreibung ein

Code wie folgt anzeigen:

import cv2

from matplotlib import pyplot as plt

img1 = cv2.imread('toukui.png')
#将图片转换为灰度图
img = cv2.cvtColor(img1,cv2.COLOR_BGR2GRAY)

template1 = cv2.imread('toukui2.png')

template = cv2.cvtColor(template1,cv2.COLOR_BGR2GRAY)

th, tw = template.shape[::]
rv = cv2.matchTemplate(img,template,cv2.TM_SQDIFF)

minVal, maxVal, minLoc, maxLoc = cv2.minMaxLoc(rv)
topLeft = minLoc
bottomRight = (topLeft[0] + tw, topLeft[1] + th)
cv2.rectangle(img,topLeft, bottomRight, 255, 2)
plt.subplot(121),plt.imshow(rv,cmap = 'gray')
plt.title('Matching Result'), plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(img,cmap = 'gray')
plt.title('Detected Point'), plt.xticks([]), plt.yticks([])
plt.show()

Laufergebnis:

Fügen Sie hier eine Bildbeschreibung ein
Der einfache Zielerkennungseffekt ist da.

Mehrfacher Vorlagenabgleich

Das heißt, bei der Zielerkennung erscheinen mehrere Ziele. Im vorherigen Beispiel haben wir im Eingabebild nach dem Helm gesucht, und dieses Teilbild erschien nur einmal im gesamten Eingabebild. In einigen Fällen ist es jedoch erforderlich, mehrere übereinstimmende Ergebnisse zu finden, wenn drei Personen mit Helmen unter der Kamera stehen. Die Funktion cv2.minMaxLoc() kann nur den Maximalwert finden, aber nicht die Standortinformationen aller übereinstimmenden Bereiche liefern. Wenn Sie mehrere Ergebnisse abgleichen möchten, ist es daher nicht möglich, die Funktion cv2.minMaxLoc() zu verwenden, und Sie müssen einen Schwellenwert für die Verarbeitung verwenden.

Im Folgenden wird Schritt für Schritt beschrieben, wie Sie das Ergebnis des Multi-Template-Abgleichs erhalten.

1. Holen Sie sich den Satz passender Standorte

Die Funktion where() kann eine Sammlung von Vorlagenübereinstimmungspositionen abrufen. Für verschiedene Eingaben ist der zurückgegebene Wert unterschiedlich.

  • Wenn die Eingabe (Parameter) ein eindimensionales Array ist, ist der Rückgabewert ein eindimensionaler Index und es gibt nur einen Satz von Indexarrays.
  • Wenn die Eingabe ein zweidimensionales Array ist, ist die Rückgabe der Positionsindex des übereinstimmenden Werts, sodass es zwei Sätze von Indexarrays gibt, die die Position des Rückgabewerts angeben.

Der folgende Code findet den Index des Elements, dessen Wert größer als 5 im eindimensionalen Array a ist (d. h. die Position des Elements und der Index des Arrays beginnt bei 0):

import numpy as np
a=np.array([3,6,8,1,2,88])
b=np.where(a>5)
print(b)

Das von diesem Code zurückgegebene Ergebnis ist:

(array([1, 2, 5], dtype=int64),)

说明索引值为 1、2、5 的数组元素,它们的值是大于 5 的


Das Obige beschreibt die Situation, wenn der Eingabewert ein eindimensionales Array ist.

Wenn der Eingabewert ein zweidimensionales Array ist, gibt die Funktion where() den Index des Werts im zweidimensionalen Array zurück, der die Bedingung erfüllt.

Der folgende Code findet beispielsweise den Index eines Elements im zweidimensionalen Array am, das einen Wert größer als 5 hat:

import numpy as np
am=np.array([[3,6,8,77,66],[1,2,88,3,98],[11,2,67,5,2]])
b=np.where(am>5)
print(b)

Das von diesem Code zurückgegebene Ergebnis ist:

(array([0, 0, 0, 0, 1, 1, 2, 2], dtype=int64),
array([1, 2, 3, 4, 2, 4, 0, 2], dtype=int64))

Die obigen Ergebnisse zeigen, dass es ein zweidimensionales Array am gibt und sein Wert ist:

[[ 3 6 8 77 66]
[ 1 2 88 3 98]
[11 2 67 5 2]]

Unter diesen [0, 1]、[0, 2]、[0, 3]、[0, 4]、[1, 2]、[1, 4]、[2, 0]、[2, 2]ist der Wert des Elements an der Position größer als 5.

Zusammenfassend lässt sich sagen, dass die Funktion np.where() herausfinden kann, 函数 cv2.matchTemplate()welche Positionen des Rückgabewerts größer als der Schwellenwert sind.

In der spezifischen Implementierung kann folgende Anweisung verwendet werden:

loc = np.where( res >= Schwellenwert)

In der Formel:

  • res ist der Rückgabewert der Funktion cv2.matchTemplate() nach dem Vorlagenabgleich.
  • Schwellenwert ist der voreingestellte Schwellenwert
  • loc ist ein Indexsatz von Pixeln, die „res >= Schwelle“ erfüllen. Im obigen zweidimensionalen Array am ist beispielsweise der zurückgegebene Elementindexsatz größer als 5 (array([0, 0, 0, 0, 1, 1, 2, 2], dtype=int64), array([ 1 , 2, 3, 4,2, 4, 0, 2], dtype=int64)). Die beiden Elemente im Rückgabewert loc stellen den Zeilenindex und den Spaltenindex des übereinstimmenden Werts dar.

2. Zyklischer Koordinatenwert

Solange man weiß, was ein Zyklus ist, sollte man sich das nicht ansehen

Um beispielsweise mehrere Werte zu verarbeiten, müssen Sie normalerweise eine Schleife verwenden.
Wenn es beispielsweise eine Liste mit den Werten 71, 23 und 16 gibt und Sie diese Werte einzeln ausgeben möchten, können Sie den Code wie folgt schreiben:

value = [71,23,16]
for i in value:
print('value 内的值:', i)

Wenn Sie den obigen Code ausführen, erhalten Sie folgende Ausgabe:

value 内的值: 71
value 内的值: 23
value 内的值: 16

Daher kann nach Erhalt des Indexsatzes übereinstimmender Werte die folgende Anweisung verwendet werden, um alle übereinstimmenden Positionen zu durchlaufen und diese Positionen zu markieren: für
i im übereinstimmenden Positionssatz: Übereinstimmende Positionen markieren.

3. Verwendung der Funktion zip() in einer Schleife

Die Funktion zip() nimmt ein iterierbares Objekt als Parameter, packt die entsprechenden Elemente im Objekt in Tupel und gibt dann eine Liste aus diesen Tupeln zurück.

Der folgende Code verwendet beispielsweise die Funktion zip(), um die entsprechenden Elemente in t in Tupel zu packen und eine Liste aus diesen Tupeln auszugeben:

x = [1,2,3]
y = [4,5,6]
z = [7,8,9]
t = (x,y,z)
print(t)
for i in zip(*t):
 print(i)

Im obigen Code gibt die Anweisung print(t) die Elemente in t aus und das Ergebnis ist:

([1, 2, 3], [4, 5, 6], [7, 8, 9])

Die Schleifenanweisung für i in zip(*t) packt die Elemente in t in Tupel und gibt sie aus. Das Ergebnis ist:

(1, 4, 7)
(2, 5, 8)
(3, 6, 9)

Wenn Sie daher den von np.where() zurückgegebenen Vorlagen-Matching-Indexsatz durchlaufen möchten, können Sie die folgende Anweisung verwenden:

for i in zip(*template Matching Index Collection): Tag-Verarbeitung


Verwenden Sie beispielsweise für das oben erwähnte Array die Funktion zip(), um eine Schleife auszuführen, und Sie können den Satz von Elementindizes größer als 5 erhalten :

import numpy as np
am=np.array([[3,6,8,77,66],[1,2,88,3,98],[11,2,67,5,2]])
print(am)
b=np.where(am>5)
for i in zip(*b):
 print(i)

Die Ausgabe des obigen Codes ist:

[[ 3 6 8 77 66]
[ 1 2 88 3 98]
[11 2 67 5 2]]
(0, 1)
(0, 2)
(0, 3)
(0, 4)
(1, 2)
(1, 4)
(2, 0)
(2, 2)

4. Passen Sie die Koordinaten an

Die Funktion numpy.where() kann den Satz von Vorlagenübereinstimmungspositionen abrufen, die die Bedingungen erfüllen, und dann kann die Funktion verwendet werden cv2.rectangle()在上述匹配位置绘制矩形来标注匹配位置.
Verwenden Sie die Funktion numpy.where(), um den angegebenen Wert im Ausgabewert der Funktion cv2.matchTemplate() zu finden, und der erhaltene Positionsindex hat die Form „(Zeilennummer, Spaltennummer)“.

Der Parameter zur Angabe des Scheitelpunkts in der Funktion cv2.rectangle() verwendet jedoch den
Positionsindex in der Form „(Spaltennummer, Zeilennummer)“. Daher muss vor der Verwendung der Funktion cv2.rectangle() zum Zeichnen eines Rechtecks ​​der von der Funktion numpy.where() erhaltene Positionsindex „getauscht“ werden. Die folgende Anweisung kann verwendet werden, um die Positionen von Zeilen und Spalten in loc auszutauschen: loc[::-1]
Die folgende Anweisung tauscht die Positionen zweier Elemente in loc aus:

import numpy as np
loc = ([1,2,3,4],[11,12,13,14])
print(loc)
print(loc[::-1])

Unter diesen ist die der Anweisung print(loc) entsprechende Ausgabe:

([1, 2, 3, 4], [11, 12, 13, 14])

Die Ausgabe entsprechend der Anweisung print(loc[::-1]) ist:

([11, 12, 13, 14], [1, 2, 3, 4])

5. Markieren Sie den Ort des passenden Bildes

Der letzte Schritt besteht darin, die Funktion cv2.rectangle() zu verwenden, um die spezifische Position des passenden Bildes zu markieren und das zu markierende Originalbild, die diagonalen Scheitelpunkte, die Farbe und die Breite der Rechteckkante anzugeben.
Bezüglich der diagonalen Eckpunkte eines Rechtecks:

  • Einer der diagonalen Scheitelpunkte A kann aus der ermittelten „Übereinstimmungspositionssammlung“, die die Bedingungen erfüllt, über die for-Schleifenanweisung erhalten werden.
  • Ein weiterer diagonaler Scheitelpunkt kann durch Berechnen der Position des Scheitelpunkts A sowie der Breite (w) und Höhe (h) der Vorlage ermittelt werden.

Somit lautet die Aussage, die jeden übereinstimmenden Ort markiert:

for i in 匹配位置集合:
 cv2.rectangle(输入图像,i, (i[0] + w, i[1] + h), 255, 2)

Codebeispiel: Verwenden Sie den Vorlagenabgleich, um mehrere Unterbilder in einem Eingabebild zu markieren, die mit einem Vorlagenbild übereinstimmen.

Code wie folgt anzeigen:

import cv2
import numpy as np
img = cv2.imread('lena4.bmp',0)
template = cv2.imread('lena4Temp.bmp',0)
w, h = template.shape[::-1]
res = cv2.matchTemplate(img,template,cv2.TM_CCOEFF_NORMED)
threshold = 0.9
loc = np.where( res >= threshold)
for pt in zip(*loc[::-1]):
  cv2.rectangle(img, pt, (pt[0] + w, pt[1] + h), 255, 1)

cv2.imshow("template",template)
cv2.imshow("result1",img)
cv2.waitKey()
cv2.destroyAllWindows()

Das Ergebnis der Operation ist wie folgt:

Fügen Sie hier eine Bildbeschreibung ein
Es ist ersichtlich, dass mehrere Untergraphen markiert sind, die mit dem Vorlagenbild im Eingabebild übereinstimmen

Supongo que te gusta

Origin blog.csdn.net/hai411741962/article/details/132209458
Recomendado
Clasificación