SIFT mit OpenCV in Python

Manav Narula 15 Februar 2024
  1. SIFT-Algorithmus zur Merkmalsextraktion
  2. Verwenden Sie die Klasse SIFT, um SIFT mit OpenCV in Python zu implementieren
  3. Passen Sie zwei Bilder an, indem Sie den SIFT-Algorithmus mit OpenCV in Python implementieren
  4. Abschluss
SIFT mit OpenCV in Python

Die Merkmalsextraktion ist ein integraler Prozess in der Bildverarbeitung und im maschinellen Lernen. Es bezieht sich auf die Umwandlung von Rohdaten in Informationen durch Extrahieren wertvoller Informationsbits.

In der Bildverarbeitung finden wir gültige Schlüsselpunkte und ihre Deskriptoren.

In Python verwenden wir die OpenCV-Bibliothek, um Bilder zu verarbeiten und zu betreiben. Mit dieser Bibliothek können wir verschiedene Techniken und vordefinierte Algorithmen anwenden.

Dieses Tutorial zeigt, wie der SIFT-Algorithmus mit OpenCV implementiert und für den Feature-Matching in Python verwendet wird. Wir werden auch lernen, zwei Bilder mit dem SIFT-Algorithmus mit OpenCV in Python abzugleichen.

SIFT-Algorithmus zur Merkmalsextraktion

SIFT (Scale Invariant Feature Transform) ist eine komplexe und hilfreiche Merkmalsextraktionstechnik. Es überwindet das Problem anderer Algorithmen, die rotationsvariant oder skalierungsvariant sein können, was bedeutet, dass die extrahierten Informationen variieren können, wenn das Bild gedreht wird oder auf eine andere Größe skaliert wird.

Der SIFT-Algorithmus vermeidet all dies, indem er gültige Schlüsselpunkte und ihre Deskriptoren extrahiert. Sie ist skalen- und rotationsinvariant.

Wir haben bereits die Merkmalsextraktion besprochen. Lassen Sie uns nun die Schritte besprechen, die am SIFT-Algorithmus zur Merkmalsextraktion beteiligt sind.

Insgesamt gibt es fünf Stufen.

Scale-Space-Extrema-Erkennung

Die erste Stufe wird Scale-space Extrema Detection genannt.

Wie bereits erwähnt, benötigen wir Merkmale, die auf jeder Skala vorhanden sind. Für größere Maßstäbe benötigen wir größere Fenster.

Diese Stufe beinhaltet die Verwendung eines anderen Skalierungsparameters und die Berechnung der Differenz der Gaußschen, d. h. der Differenz der Gaußschen Unschärfe mit variierenden Skalierungsparameterwerten. Es wird eine Koordinate mit einem gegebenen Skalierungswert auswählen und prüfen, ob sie mit höheren und niedrigeren Skalierungswerten existiert.

Keypoint-Lokalisierung

Lassen Sie uns nun zu Stufe zwei übergehen, der Keypoint-Lokalisierung. In dieser Phase werden die ausgewählten Schlüsselpunkte herausgefiltert.

Es wird die Erweiterung der Skala der Taylor-Reihe verwenden, um verfeinerte Schlüsselpunkte zu erhalten und ihre Intensitäten zu finden. Wenn die Intensität kleiner als der festgelegte Schwellenwert ist, wird sie verworfen.

Orientierungsauftrag

Die nächste Stufe heißt Orientierungsaufgabe. Wie bereits erwähnt, sind die Schlüsselpunkte rotationsinvariant, und diese Stufe stellt dasselbe sicher.

Es wird die umliegenden Regionen eines Schlüsselpunkts für die Berechnung von Steigungen und deren Richtungen nehmen. Sechsunddreißig Bins werden erstellt und in einem Histogramm dargestellt, um die 360 Grad darzustellen, und die Spitzen über 80 % werden als neue Schlüsselpunkte betrachtet und verwendet, um die Ausrichtung des ausgewählten Schlüsselpunkts zu bestimmen.

Keypoint-Deskriptor

Die vierte Stufe zielt darauf ab, einen Keypoint-Deskriptor zu erstellen, indem ein 16x16-Block neben dem Keypoint genommen und in 16 Blöcke von 4x4 geteilt wird. Für jeden Block, der 8 Bins enthält, wird ein Orientierungshistogramm konstruiert.

Alle diese Werte werden als Schlüsselpunkt-Deskriptorvektor dargestellt.

Keypoint-Matching

Die letzte Stufe beinhaltet Keypoint Matching. Es passt zwei Schlüsselpunkte an, indem es ihre Nachbarn findet.

Dies wird verwendet, um falsche Übereinstimmungen zu eliminieren.

Jetzt haben wir den SIFT-Algorithmus ausführlich besprochen. Lassen Sie uns sehen, wie dies mit der OpenCV-Bibliothek von Python implementiert wird.

Verwenden Sie die Klasse SIFT, um SIFT mit OpenCV in Python zu implementieren

Mit dem Konstruktorobjekt SIFT_create() kann ein Objekt der Klasse SIFT erstellt werden, das die Schlüsselpunkte aus einem Bild erkennen kann.

Wir können verschiedene Parameter angeben, obwohl jeder Parameter einen bestimmten Standardwert hat. Die Parameter sind: nfeatures, nOctaveLayers, contrastThreshold, edgeThreshold, sigma und descriptorType.

Der Parameter nfeatures kann die Anzahl der besten Merkmale angeben, die aus dem Ergebnis ausgewählt werden sollen. Die Layer in jeder Oktave können mit dem Parameter nOctaveLayers angegeben werden, der standardmäßig auf 3 eingestellt ist.

Die Werte contrastThreshold und edgeThreshold filtern die schwachen und kantenartigen Merkmale heraus. Das Sigma von Gauß wird mit dem Parameter sigma angegeben, der für Bilder, die mit einer weichen Linse angeklickt werden, verringert werden kann.

Der letzte Parameter gibt den Typ des Deskriptors an, der entweder CV_32F oder CV_8U sein kann.

Lassen Sie uns sehen, wie diese Methode verwendet wird.

import numpy as np
import cv2 as cv

i = cv.imread("obj.png")
g = cv.cvtColor(i, cv.COLOR_BGR2GRAY)

sift_ob = cv.SIFT_create()
kp = sift_ob.detect(g, None)
img = cv.drawKeypoints(g, kp, i)

cv.imshow("Output", img)
cv.waitKey(0)
cv.destroyAllWindows()

Ausgang:

Erkennen und zeichnen Sie Schlüsselpunkte mit SIFT in OpenCV Python

Versuchen wir, das obige Beispiel zu verstehen.

Wir lesen das Bild mit der Funktion imread(). Dann haben wir dieses Bild mit der cvtColor-Methode, die den Farbraum jedes Bildes ändern kann, in Graustufen konvertiert.

Der Algorithmus funktioniert gut mit Graustufenbildern.

Wir haben ein Objekt mit der Funktion SIFT_create() mit den Standardwerten erstellt. Wir verwenden die Funktion detect() mit dem erstellten Objekt, um die Punkte im gegebenen Bild zu identifizieren; es gibt ein Tupel zurück, das das Ergebnis speichert.

Wir zeichnen die Schlüsselpunkte auf dem Bild für eine bessere visuelle Darstellung mit der Funktion drawKeypoints(). Wir übergeben das Tupel und das Bild in dieser Funktion.

Das endgültige Bild wird mit der Funktion imshow() angezeigt.

Die Funktion waitKey() verhinderte, dass sich das Ausgabefenster automatisch schließt und darauf wartet, dass der Benutzer eine Taste drückt. Wir haben das Fenster mit der Funktion destroyAllWindows() geschlossen.

SIFT existierte früher in der OpenCV Contrib-Bibliothek und wurde zu OpenCV hinzugefügt, als sein Patent im Jahr 2020 auslief. Es ist in OpenCV-Version 3.4.2.16 nicht mehr verfügbar.

Lassen Sie uns nun diskutieren, wie man zwei Bilder abgleicht, indem man den SIFT-Algorithmus mit OpenCV in Python implementiert.

Passen Sie zwei Bilder an, indem Sie den SIFT-Algorithmus mit OpenCV in Python implementieren

Wie oben besprochen, können wir mit dem SIFT-Algorithmus verschiedene Schlüsselpunkte und Deskriptoren erkennen. Dazu können wir einen Brute-Force-Matcher verwenden.

Ein Brute-Force-Matcher nimmt jeweils einen Schlüsselpunkt und seinen Deskriptor und versucht, ihn mit einer Reihe von Merkmalen aus einem anderen Bild abzugleichen, wobei er die beste Übereinstimmung zurückgibt.

Wir werden also ein Brute-Force-Matcher-Objekt mit dem Konstruktor BFMatcher() erstellen. Dieses Objekt akzeptiert zwei Parameter.

Der erste Parameter ist der normType-Parameter, also die verwendete Distanz. Für String-basiert sollten wir NORM_HAMMING verwenden, aber für unseren Fall (SIFT) können wir NORM_L1 oder NORM_l2 verwenden.

Der zweite Parameter ist crossCheck, der, wenn er auf True gesetzt ist, nur die entsprechenden Übereinstimmungen in beiden Sätzen zurückgibt. Nachdem wir das Objekt BFMatcher erstellt haben, können wir die Funktion match() verwenden, um die beiden Sätze von Deskriptoren für den Abgleich zu übergeben.

Danach können wir mit der Funktion drawMatches() die jeweiligen Übereinstimmungen auf die beiden Bilder zeichnen. Die Bilder werden nebeneinander angeordnet, und die übereinstimmenden Schlüsselpunkte werden mit einer Linie verbunden.

Jede Linie hat eine eindeutige Farbe, um das Merkmal zu identifizieren. Sehen wir uns dazu ein Beispiel an.

Wir werden die Merkmale der folgenden zwei Bilder des Qutb Minar abgleichen.

Bild 1:

Abzugleichendes Bild 1

Bild 2:

Abzugleichendes Bild 2

Code:

import cv2
import matplotlib.pyplot as plt

# %matplotlib inline

i1 = cv2.imread("q3.jpeg")
i2 = cv2.imread("q4.jpeg")

img1 = cv2.cvtColor(i1, cv2.COLOR_BGR2GRAY)
img2 = cv2.cvtColor(i2, cv2.COLOR_BGR2GRAY)

sift = cv2.SIFT_create()

k_1, des_1 = sift.detectAndCompute(img1, None)
k_2, des_2 = sift.detectAndCompute(img2, None)

bf = cv2.BFMatcher(cv2.NORM_L1, crossCheck=True)

matches = bf.match(des_1, des_2)
matches = sorted(matches, key=lambda x: x.distance)

img3 = cv2.drawMatches(img1, k_1, img2, k_2, matches[:50], img2, flags=2)
cv2.imshow("Output", img3)
cv2.waitKey(0)
cv2.destroyAllWindows()

Ausgang:

Abgleich von Bildmerkmalen mit SIFT in Python OpenCV

Im obigen Beispiel haben wir die Merkmale von zwei Bildern mit dem SIFT-Algorithmus und dem Brute-Force-Matcher abgeglichen.

Zuerst haben wir die Merkmale für die beiden Bilder mit dem SIFT-Algorithmus extrahiert. Dann haben wir diese Features mit dem Brute-Force-Matcher-Objekt abgeglichen.

Die resultierenden Übereinstimmungen wurden mit der Funktion drawMatches() auf beiden Bildern gezeichnet.

Abschluss

Dieses Tutorial demonstrierte die Implementierung des SIFT-Algorithmus für die Merkmalsextraktion mit OpenCV in Python. Die Theorie hinter dem SIFT-Algorithmus wurde ausführlich diskutiert und seine Vorteile gegenüber anderen Techniken wurden hervorgehoben.

Die fünf Stufen dieses Algorithmus wurden detailliert beschrieben. Diese waren Scale-Space Extrema Detection, Keypoint Localization, Orientation Assignment, Keypoint Descriptors und Keypoint Matching.

Wir haben die Implementierung dieser Technik besprochen, indem wir ein Objekt der Klasse SIFT mit dem Objekt SIFT_create() erstellt haben. Wir haben die Verwendung der Methode detect() dieser Klasse hervorgehoben und die Schlüsselpunkte mit der Funktion drawKeypoints() gezeichnet.

Wir haben auch den Abgleich zweier Bilder mit dem SIFT-Algorithmus unter Verwendung von OpenCV in Python besprochen. Dazu haben wir zunächst die Features mit dem SIFT-Algorithmus extrahiert; Dann haben wir ein Objekt des Brute-Force-Matchers erstellt.

Wir haben die Deskriptoren an das Attribut match() des Objekts übergeben, um die Übereinstimmungen zu finden. Das Ergebnis wurde mit der Funktion drawMatches() auf beide Bilder gezeichnet, um eine visuelle Darstellung zu geben.

Manav Narula avatar Manav Narula avatar

Manav is a IT Professional who has a lot of experience as a core developer in many live projects. He is an avid learner who enjoys learning new things and sharing his findings whenever possible.

LinkedIn

Verwandter Artikel - Python OpenCV