Es gibt viele Möglichkeiten, OpenCV-Feature-Point-Extraktion und -Anpassung zu verwenden. Bei Verwendung mehrerer Bilder dauerte das Extrahieren von Feature-Punkten häufig einige Zeit. Daher habe ich dieses Mal ein Programm erstellt, das die Feature-Point-Informationen in eine Datei ausgibt und zum Abgleichen verwendet.
Lassen Sie uns diesmal als Beispiel ein Mädchen mit roter Brille (Zielbild) von den Mädchen (12 Quellbilder) finden!
Quellbild ⬇︎
Zielbild ⬇︎
Dieses Mal haben wir uns in der folgenden Umgebung entwickelt. OpenCV 4.1.2 Python 3.8.1
Unten ist der Ablauf des Programms. Ich werde Schritt für Schritt aus dem nächsten Abschnitt erklären.
Rufen Sie zunächst die Feature-Point-Informationen des Quellbilds (Mädchen) in save_features.py ab und speichern Sie sie in einer Datei. Dieses Mal habe ich AKAZE verwendet, einen in OpenCV implementierten Feature-Point-Deskriptor. Um den "Schlüsselpunkt" als Datei zu speichern, müssen Sie auf den "cv :: KeyPoint" zugreifen und ihn auflisten.
save_features.py
#Schlüsselpunkt auflisten
keypoint = []
for p in features[0]:
temp = (p.pt, p.size, p.angle, p.response, p.octave, p.class_id)
keypoint.append(temp)
Auch dieses Mal wurden die Feature-Point-Informationen in den Bytetyp konvertiert, um den Speicherverbrauch zu reduzieren.
save_features.py
#Konvertieren Sie den Schlüsselpunkt in Bytes
map(bytes, keypoints)
Unten finden Sie den gesamten Quellcode.
save_features.py
import cv2 as cv
import pickle
SOURCE_FILES = [
"youngwoman_37.jpg ",
"youngwoman_38.jpg ",
"youngwoman_39.jpg ",
"youngwoman_40.jpg ",
"youngwoman_41.jpg ",
"youngwoman_42.jpg ",
"youngwoman_43.jpg ",
"youngwoman_44.jpg ",
"youngwoman_45.jpg ",
"youngwoman_46.jpg ",
"youngwoman_47.jpg ",
"youngwoman_48.jpg ",
]
def get_features(img_file_name):
"""Get features of master images
Args:
img_file_name(list): Master image
Returns:
keypoints, descriptors, img
"""
img = cv.imread("images/" + img_file_name)
#Extraktion von Feature-Point-Informationen
akaze = cv.AKAZE_create()
kp, des = akaze.detectAndCompute(img, None)
features = [kp, des]
return features
sources = {}
for item in SOURCE_FILES:
features = get_features(item)
#Schlüsselpunkt auflisten
keypoints = []
for p in features[0]:
temp = (p.pt, p.size, p.angle, p.response, p.octave, p.class_id)
keypoints.append(temp)
#Konvertieren Sie Schlüsselpunkte in Bytes
map(bytes, keypoints)
#Charakteristische Punktinformationen werden in ein Wörterbuch umgewandelt
sources[item] = {
"src": item,
"keypoint": keypoints,
"descriptor": features[1],
}
#Schreiben Sie Feature-Point-Informationen in eine Datei
with open("sources_data.pickle", mode="wb") as f:
pickle.dump(sources, f)
Die Verarbeitung erfolgt in get_features_from_file.py ab Schritt 2. Wie beim Quellbild werden Merkmalspunktinformationen mit AKAZE erfasst, einem Merkmalspunktdeskriptor.
get_features_from_file.py
#Zielbild laden
target_img = cv.imread("images/target_girl.jpg ")
#Funktionserfassung
akaze = cv.AKAZE_create()
target_keypoint, target_descriptor = akaze.detectAndCompute(target_img, None)
Holen Sie sich Feature-Point-Informationen aus der Datei mit get_sources ()
.
Da "Schlüsselpunkte" in Byte konvertiert wurden, um es zum Einlegen zu bringen, wird es in eine Liste konvertiert und zur ursprünglichen Struktur zurückgeführt.
get_features_from_file.py
def get_sources():
"""Get source's features from file
Returns:
sources(list): source's keypoints, descriptors,and img
"""
#Informationen zu Feature-Punkten aus der Datei abrufen
with open("sources_data.pickle", mode="rb") as f:
sources = pickle.load(f)
for n in sources:
items = sources[n]
#Ändern Sie die Schlüsselpunkte von Bytes in Liste
list(map(list, items["keypoint"]))
#Stellen Sie die Schlüsselpunkte in der ursprünglichen Struktur wieder her
keypoints = []
for p in items["keypoint"]:
temp = cv.KeyPoint(
x=p[0][0],
y=p[0][1],
_size=p[1],
_angle=p[2],
_response=p[3],
_octave=p[4],
_class_id=p[5],
)
keypoints.append(temp)
items["keypoint"] = keypoints
return sources
Stimmt mit den Merkmalspunktinformationen des Zielbilds für jedes Quellbild überein. Die Daten werden ausgedünnt, und wenn die Anzahl der übereinstimmenden Merkmalspunkte gleich oder größer als der festgelegte Schwellenwert ist (diesmal auf 20 festgelegt), ist der Abgleich erfolgreich.
get_features_from_file.py
for n in sources:
source = sources[n]
source_img = cv.imread("images/" + source["src"])
matches = matcher.knnMatch(source["descriptor"], target_des, k=2)
#Daten ausdünnen
ratio = 0.5
matched_keypoints = []
for m, n in matches:
if m.distance < ratio * n.distance:
matched_keypoints.append([m])
#Ausgabe-Ergebnisbild, wenn mehr als ein Schwellenwert vorhanden ist
if len(matched_keypoints) > 20:
out = cv.drawMatchesKnn(
source_img,
source["keypoint"],
target_img,
target_kp,
matched_keypoints,
None,
flags=2,
)
Unten finden Sie den gesamten Quellcode.
get_features_from_file.py
import cv2 as cv
import pickle
def get_sources():
"""Get source's features from file
Returns:
sources(list): source's keypoints, descriptors,and img
"""
#Informationen zu Feature-Punkten aus der Datei abrufen
with open("sources_data.pickle", mode="rb") as f:
sources = pickle.load(f)
for n in sources:
items = sources[n]
#Ändern Sie die Schlüsselpunkte von Bytes in Liste
list(map(list, items["keypoint"]))
#Stellen Sie die Schlüsselpunkte in der ursprünglichen Struktur wieder her
keypoints = []
for p in items["keypoint"]:
temp = cv.KeyPoint(
x=p[0][0],
y=p[0][1],
_size=p[1],
_angle=p[2],
_response=p[3],
_octave=p[4],
_class_id=p[5],
)
keypoints.append(temp)
items["keypoint"] = keypoints
return sources
matcher = cv.BFMatcher()
#Zielbild laden
target_img = cv.imread("images/target_girl.jpg ")
#Funktionserfassung
akaze = cv.AKAZE_create()
target_kp, target_des = akaze.detectAndCompute(target_img, None)
#Lesen Sie die Feature-Point-Informationen des Quellbilds aus der Datei
sources = get_sources()
for n in sources:
source = sources[n]
source_img = cv.imread("images/" + source["src"])
matches = matcher.knnMatch(source["descriptor"], target_des, k=2)
#Daten ausdünnen
ratio = 0.5
matched_keypoints = []
for m, n in matches:
if m.distance < ratio * n.distance:
matched_keypoints.append([m])
#Ausgabe-Ergebnisbild, wenn mehr als ein Schwellenwert vorhanden ist
if len(matched_keypoints) > 20:
out = cv.drawMatchesKnn(
source_img,
source["keypoint"],
target_img,
target_kp,
matched_keypoints,
None,
flags=2,
)
cv.imwrite("images/result.jpg ", out)
cv.waitKey()
Im folgenden Ergebnisbild werden die zwischen dem Quellbild und dem Zielbild übereinstimmenden Merkmalspunkte gezeichnet. Ich konnte das Zielmädchen sicher finden!
Der Schlüssel zum Speichern von Feature-Punkten in einer Datei ist
Zugriff auf cv :: KeyPoint
Erstellen Sie eine Liste basierend auf den Informationen, auf die zugegriffen wird
ist.
Wenn Sie die Möglichkeit haben, Bilder mit OpenCV zu verarbeiten, probieren Sie es bitte aus.
Exportieren Sie KeyPoint von OpenCV für Python 3 in eine Datei
[Feature Point Matching mit Python3, OpenCV3 (AKAZE, KNN)] (https://techtech-sorae.com/python3opencv3%E3%81%A7%E7%89%B9%E5%BE%B4%E7%82%B9%E3%83%9E%E3%83%83%E3%83%81%E3%83%B3%E3%82%B0akaze-knn/)
Recommended Posts