So ein Typ. Feature-Punkte werden erkannt und zwischen einem 400 x 400 Pixel großen Bild und einem 200 x 200 Pixel großen und gedrehten Bild angepasst.
Dies ist der Code, der das obige Bild ausgibt. nur das.
import cv2
from IPython.display import Image
from IPython.display import display
#Bild wird geladen
img1 = cv2.imread('/path/to/dir/megane400x400.png')
img2 = cv2.imread('/path/to/dir/megane200x200_rotate.png')
#Funktionspunkterkennung
akaze = cv2.AKAZE_create()
kp1, des1 = akaze.detectAndCompute(img1, None)
kp2, des2 = akaze.detectAndCompute(img2, None)
#passend
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
matches = bf.match(des1, des2)
#Sortieren Sie nach dem Brummabstand zwischen den Feature-Punkten
matches = sorted(matches, key=lambda x: x.distance)
#Erstellen Sie ein passendes Ergebnisbild zwischen 2 Bildern
img1_2 = cv2.drawMatches(img1, kp1, img2, kp2, matches[:10], None, flags=2)
decoded_bytes = cv2.imencode('.jpg', img1_2)[1].tobytes()
display(Image(data=decoded_bytes))
img1 = cv2.imread('/path/to/dir/megane400x400.png')
img2 = cv2.imread('/path/to/dir/megane200x200_rotate.png')
print(img1)
# [[[255 255 255]
# [255 255 255]
# [255 255 255]
# ...
# [255 255 255]
# [255 255 255]
# [255 255 255]]
#
# [[255 255 255]
# [255 255 255]
# [255 255 255]
# ...
# [255 255 255]
# [255 255 255]
# [255 255 255]]
#
# ...
#
# [[255 255 255]
# [255 255 255]
# [255 255 255]
# ...
# [255 255 255]
# [255 255 255]
# [255 255 255]]
#
# [[255 255 255]
# [255 255 255]
# [255 255 255]
# ...
# [255 255 255]
# [255 255 255]
# [255 255 255]]]
print(img1.shape)
# (400, 400, 3)
Der BGR-Wert pro Pixel wird zurückgegeben. Bei der Methode cv2.imread () wird BGR (die Reihenfolge der Werte ist unterschiedlich) anstelle von RGB verwendet. Beachten Sie, dass es bei Verwendung mit Pillow in RGB konvertiert werden muss. Siehe auch: https://note.nkmk.me/python-opencv-bgr-rgb-cvtcolor/
Dies ist ein 400x400px-Bild, daher ist die Form (400, 400, 3). [255 255 255] <- Dies ist der BGR-Wert pro Pixel. Im weißen Teil des Bildes sind [255 255 255] aufgereiht.
akaze = cv2.AKAZE_create()
kp1, des1 = akaze.detectAndCompute(img1, None)
kp2, des2 = akaze.detectAndCompute(img2, None)
print('#####Funktionspunkt#####')
print(kp1)
# [<KeyPoint0x11af41db0>, <KeyPoint0x11af649c0>, <KeyPoint0x11af64ba0>,
# ...
# <KeyPoint 0x126265030>, <KeyPoint 0x126265120>, <KeyPoint 0x126265150>]
#Der erkannte Feature-Punkt ist cv2.Wird als Array in der KeyPoint-Klasse zurückgegeben.
print('#####Anzahl der Feature-Punkte#####')
print(len(kp1))
# 143
#Anzahl der Merkmalspunkte Variiert je nach Art und Größe des Bildes
#Sie können die Anzahl der Feature-Punkte erhöhen, indem Sie das Bild vergrößern. Wenn es jedoch einen bestimmten Wert überschreitet, wird nur der Rechenaufwand erhöht. Erhöhen Sie ihn daher, während Sie die Ausgabe überprüfen.
print('#####Feature-Deskriptor#####')
print(des1)
# [[ 32 118 2 ... 253 255 0]
# [ 33 50 12 ... 253 255 48]
# [ 0 134 0 ... 253 255 32]
# ...
# [ 74 24 240 ... 128 239 31]
# [245 25 122 ... 255 239 31]
# [165 242 15 ... 127 238 55]]
#AKAZE kehrt als 61-dimensionaler Vektor zurück
print('#####Merkmalsvektor#####')
print(des1.shape)
# (143, 61) <- (58 ist die Anzahl der Merkmalspunkte,Anzahl der Elemente im Feature-Deskriptor)
AKAZE ist einer der Algorithmen zur Erkennung von Merkmalspunkten und hat dieselbe Standposition wie ORB, SIFT, SURF usw. Es scheint Vorteile wie schnelle Berechnungsgeschwindigkeit und Benutzerfreundlichkeit zu haben, da es Open Source ist.
Demnach scheint AKAZE eine höhere Erkennungsgenauigkeit als ORB zu haben. https://docs.opencv.org/3.0-rc1/dc/d16/tutorial_akaze_tracking.html
Zitat: http://labs.eecs.tottori-u.ac.jp/sd/Member/oyamada/OpenCV/html/py_tutorials/py_feature2d/py_features_meaning/py_features_meaning.html#features-meaning
A ~ F ist ein Teil, der aus diesem Bild ausgeschnitten ist. Wissen Sie, wo sich das zugeschnittene Bild befindet? Ich denke, viele Menschen haben einen solchen Eindruck.
A, B-> Ich verstehe, dass es der Himmel und die Wand sind, aber es ist schwierig, den Ort zu bestimmen. (eben) C, D-> Sie können sehen, dass es sich irgendwo im oberen Teil des Gebäudes befindet. Es ist jedoch schwierig, den genauen Ort zu bestimmen. (Kante) E, F-> Sie können die Ecke des Gebäudes leicht sehen. (Ecke)
Daraus ergibt sich, dass Teile wie E und F gute Eigenschaften sind. Um Ecken wie E und F zu finden, erkennen Algorithmen wie AKAZE Bereiche mit großen Helligkeitsänderungen.
Referenz: http://www.lab.kochi-tech.ac.jp/yoshilab/thesis/1150295.pdf
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
matches = bf.match(des1, des2)
matches = sorted(matches, key=lambda x: x.distance)
print(matches)
#Übereinstimmende Feature-Punkte sind cv2.Wird als Array als DMatch-Klasse zurückgegeben
# [<DMatch 0x1260f5150>, <DMatch 0x1260f5490>, ... <DMatch 0x1260f65f0>, <DMatch 0x1260f69d0>]
print(len(matches))
# 58
print('###Abstand zwischen Feature-Deskriptoren###')
for i in matches:
print(i.distance)
# 6.0
# 6.0
# .
# .
# .
# 142.0
# 150.0
BFMatcher berechnet den Abstand des Merkmalsmengen-Deskriptors, der aus zwei Bildern (hier der Brummabstand) durch Runden erhalten wird, und stimmt mit dem nächstgelegenen überein. Das erste Argument von BFMatcher (), cv2.NORM_HAMMING, gibt die Berechnung der Brummentfernung nach Entfernung an. Der Standard-CrossCheck für das erste Ladeargument ist False, wodurch eine Asymmetrie entsteht, bei der ein Schlüsselpunkt am nächsten liegt, der andere jedoch näher. Wenn True festgelegt ist, wird nur das Ergebnis mit beiden kürzesten zurückgegeben.
Sortieren nach Rückgabewert durch Übergeben einer Funktion an den Argumentschlüssel von sorted ().
--matches-> Liste der Objekte vom Typ DMatch --DMatch.distance-> Je geringer der Abstand zwischen Feature-Deskriptoren ist, desto höher ist der Übereinstimmungsgrad. --DMatch.trainIdx-> Index des Deskriptors im Trainingsdeskriptor (Referenzdaten) --DMatch.queryIdx-> Index des Deskriptors im Abfragedeskriptor (Suchdaten) --DMatch.imgIdx-> Index des Trainingsbildes
Die Anzahl der verschiedenen Zeichen an den entsprechenden Positionen in zwei Zeichenfolgen mit der gleichen Anzahl von Zeichen.
• Der Brummabstand zwischen 1011101 und 1001001 beträgt 2. • Der Brummabstand zwischen 2173896 und 2233796 beträgt 3. -Der Brummabstand zwischen "getönt" und "Rosen" beträgt 3.
def1 und def2, die an bf.match () übergeben werden, sind Arrays, die mehrere 61-dimensionale Feature-Deskriptoren enthalten.
print(des1)
# [[ 32 118 2 ... 253 255 0] <-61 Stück
# [ 33 50 12 ... 253 255 48] <-61 Stück
# [ 0 134 0 ... 253 255 32]
# ...
# [ 74 24 240 ... 128 239 31]
# [245 25 122 ... 255 239 31]
# [165 242 15 ... 127 238 55]
Es scheint, dass die folgende Verarbeitung in bf.match () erfolgt.
Sie können sehen, dass es in Dezimal-> Binär konvertiert wurde.
#0 ist eine Binärzahl 00000000
des1 = np.array([0]).astype('uint8')
#255 ist eine Binärzahl 11111111
des2 = np.array([255]).astype('uint8')
# ※ astype('uint8')Wenn nicht, bf.match()Ich kann es dir nicht geben.
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
matches = bf.match(des1, des2)
matches = sorted(matches, key=lambda x: x.distance)
for i in matches:
print(i.distance)
# 8.0 <-Summende Distanz
#244 ist eine Binärzahl 11111110
des1 = np.array([244]).astype('uint8')
#255 ist eine Binärzahl 11111111
des2 = np.array([255]).astype('uint8')
# ※ astype('uint8')Wenn nicht, bf.match()Ich kann es dir nicht geben.
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
matches = bf.match(des1, des2)
for i in matches:
print(i.distance)
# 1.0 <-Summende Distanz
Sie können sehen, dass wir die Abstände zwischen den Elementen im Feature-Deskriptor summieren.
#Eine binäre Darstellung ist durch Hinzufügen eines 0b-Präfixes möglich.
des1 = np.array([[0b0001, 0b0001, 0b0001], [0b0011, 0b0011, 0b0011], [0b0111, 0b0111, 0b0111]]).astype('uint8')
des2 = np.array([[0b0000, 0b0000, 0b0000]]).astype('uint8')
# ※ astype('uint8')Wenn nicht, bf.match()Ich kann es dir nicht geben.
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
matches = bf.match(des1, des2)
# [0b0001, 0b0001, 0b0001]Wann[0b0000, 0b0000, 0b0000]Nur das Ergebnis von
for i in matches:
print(i.distance)
# 3.0 <-Summende Distanz
img1_2 = cv2.drawMatches(img1, kp1, img2, kp2, matches[:10], None, flags=2)
decoded_bytes = cv2.imencode('.jpg', img1_2)[1].tobytes()
display(Image(data=decoded_bytes)
Durch Setzen von Übereinstimmungen [: 10] im Argument von drawMatches () werden 10 nahe beieinander liegende Feature-Punkte von oben gezeichnet.
Recommended Posts