[PYTHON] Comment enregistrer les informations de point caractéristique de l'image dans un fichier et l'utiliser pour la mise en correspondance

introduction

Il existe de nombreuses possibilités d'utiliser l'extraction et la correspondance de points d'entités OpenCV. Lors de l'utilisation de plusieurs images, l'extraction des points caractéristiques prenait souvent du temps. Par conséquent, cette fois, j'ai créé un programme qui génère les informations sur les points caractéristiques dans un fichier et les utilise pour la correspondance.

Cette fois, à titre d'exemple, trouvons une fille aux lunettes rouges (image cible) parmi les filles (12 images source)!

Image source ⬇︎ youngwoman_37.jpgyoungwoman_38.jpgyoungwoman_39.jpgyoungwoman_40.jpg

youngwoman_41.jpgyoungwoman_42.jpgyoungwoman_43.jpgyoungwoman_44.jpg

youngwoman_45.jpgyoungwoman_46.jpgyoungwoman_47.jpgyoungwoman_48.jpg

Image cible ⬇︎ target_girl.jpg

Environnement de développement

Cette fois, nous avons développé dans l'environnement suivant. OpenCV 4.1.2 Python 3.8.1

Constitution

Voici le déroulement du programme. J'expliquerai étape par étape dans la section suivante.

  1. Obtenez les informations sur les points caractéristiques de l'image source et enregistrez-les dans un fichier
  2. Obtenez des informations sur les points caractéristiques de l'image cible
  3. Obtenir des informations sur les points caractéristiques de l'image source à partir du fichier
  4. Correspondance

1. Obtenez les informations sur les points caractéristiques de l'image source et enregistrez-les dans un fichier

Tout d'abord, save_features.py pour obtenir les informations sur les points caractéristiques de l'image source (filles) et les enregistrer dans un fichier. Cette fois, j'ai utilisé AKAZE, un descripteur de point de fonction implémenté dans OpenCV. Pour enregistrer le keypoint en tant que fichier, vous devez accéder et lister le cv :: KeyPoint.

save_features.py


#Liste des points clés
keypoint = []
for p in features[0]:
    temp = (p.pt, p.size, p.angle, p.response, p.octave, p.class_id)
    keypoint.append(temp)

De plus, cette fois, les informations sur les points caractéristiques ont été converties en octets afin de réduire la consommation de mémoire.

save_features.py


#Convertir le point-clé en octets
map(bytes, keypoints)

Voici le code source complet.

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)

    #Extraction d'informations sur les points caractéristiques
    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)
    #Liste des points clés
    keypoints = []
    for p in features[0]:
        temp = (p.pt, p.size, p.angle, p.response, p.octave, p.class_id)
        keypoints.append(temp)

    #Convertir les points-clés en octets
    map(bytes, keypoints)
    #Les informations sur les points caractéristiques sont converties dans un dictionnaire
    sources[item] = {
        "src": item,
        "keypoint": keypoints,
        "descriptor": features[1],
    }

#Écrire des informations sur les points caractéristiques dans un fichier
with open("sources_data.pickle", mode="wb") as f:
    pickle.dump(sources, f)

2. Obtenez des informations sur les points caractéristiques de l'image cible

Le traitement est effectué dans get_features_from_file.py à partir de l'étape 2. Comme pour l'image source, les informations sur les points caractéristiques sont acquises à l'aide d'AKAZE, qui est un descripteur de points caractéristiques.

get_features_from_file.py


#Charger l'image cible
target_img = cv.imread("images/target_girl.jpg ")
#Acquisition de fonctionnalités
akaze = cv.AKAZE_create()
target_keypoint, target_descriptor = akaze.detectAndCompute(target_img, None)

3. Obtenir des informations sur les points caractéristiques de l'image source à partir du fichier

Obtenez des informations sur les points caractéristiques du fichier avec get_sources (). Puisque keypoints a été converti en octet afin de le rendre pickle, il est converti en liste et renvoyé à la structure d'origine.

get_features_from_file.py


def get_sources():
    """Get source's features from file

        Returns:
            sources(list): source's keypoints, descriptors,and img
        """
    #Obtenir des informations sur les points caractéristiques d'un fichier
    with open("sources_data.pickle", mode="rb") as f:
        sources = pickle.load(f)

    for n in sources:
        items = sources[n]
        #Changer les points-clés d'octets en liste
        list(map(list, items["keypoint"]))
        #Restaurer les points clés à la structure d'origine
        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

4. Correspondance

Correspond aux informations de point caractéristique de l'image cible pour chaque image source. Les données sont éclaircies et si le nombre de points caractéristiques correspondants est égal ou supérieur au seuil défini (défini sur 20 cette fois), la correspondance est réussie.

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)
    #Affiner les données
    ratio = 0.5
    matched_keypoints = []
    for m, n in matches:
        if m.distance < ratio * n.distance:
            matched_keypoints.append([m])

    #Image de résultat de sortie lorsqu'il y a plus de bons que n'importe quel seuil
    if len(matched_keypoints) > 20:
        out = cv.drawMatchesKnn(
            source_img,
            source["keypoint"],
            target_img,
            target_kp,
            matched_keypoints,
            None,
            flags=2,
        )

Voici le code source complet.

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
        """
    #Obtenir des informations sur les points caractéristiques d'un fichier
    with open("sources_data.pickle", mode="rb") as f:
        sources = pickle.load(f)

    for n in sources:
        items = sources[n]
        #Changer les points-clés d'octets en liste
        list(map(list, items["keypoint"]))
        #Restaurer les points clés à la structure d'origine
        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()

#Charger l'image cible
target_img = cv.imread("images/target_girl.jpg ")
#Acquisition de fonctionnalités
akaze = cv.AKAZE_create()
target_kp, target_des = akaze.detectAndCompute(target_img, None)
#Lire les informations de point caractéristique de l'image source à partir du fichier
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)
    #Affiner les données
    ratio = 0.5
    matched_keypoints = []
    for m, n in matches:
        if m.distance < ratio * n.distance:
            matched_keypoints.append([m])

    #Image de résultat de sortie lorsqu'il y a plus de bons que n'importe quel seuil
    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()

résultat

Dans l'image de résultat ci-dessous, les points caractéristiques correspondant entre l'image source et l'image cible sont dessinés. J'ai pu trouver la fille cible en toute sécurité! image.png

À la fin

La clé pour enregistrer des points caractéristiques dans un fichier est Accéder à cv :: KeyPoint Faire une liste en fonction des informations consultées est. Si vous avez la possibilité de traiter des images avec OpenCV, veuillez l'essayer.

Page de référence

Exporter KeyPoint d'OpenCV pour Python 3 vers un fichier

[Correspondance des points de fonction avec 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

Comment enregistrer les informations de point caractéristique de l'image dans un fichier et l'utiliser pour la mise en correspondance
Extrayez les informations de paroles dans le fichier MP3 / MP4 et enregistrez-les dans le fichier de paroles (* .lrc) pour Sony Walkman.
[Introduction à Python] Comment utiliser l'opérateur in dans l'instruction for?
Comment obtenir les coordonnées de sommet d'une entité dans ArcPy
Démarrez la webcam, prenez une image fixe et enregistrez-la localement
Utilisez Cloud Dataflow pour modifier dynamiquement la destination en fonction de la valeur des données et enregistrez-la dans GCS
L'histoire de la création d'un outil pour charger une image avec Python ⇒ l'enregistrer sous un autre nom
Comment compter le nombre d'éléments dans Django et sortir dans le modèle
Utilisez Pillow pour rendre l'image transparente et en superposer une partie seulement
Enregistrez le tableau numpy dans un fichier wav à l'aide du module wave
Comment lire les fichiers de numéros de série en boucle, les traiter et les représenter graphiquement
Comment utiliser Decorator dans Django et comment le créer
Comment afficher la date de modification d'un fichier en langage C jusqu'à nanosecondes
Enregistrez le modèle pystan et les résultats dans un fichier pickle
Comment utiliser la méthode __call__ dans la classe Python
Comparaison de l'utilisation des fonctions d'ordre supérieur dans Python 2 et 3
Comment dessiner de manière interactive un pipeline d'apprentissage automatique avec scikit-learn et l'enregistrer au format HTML
J'ai créé une fonction pour découper l'image de python openCV, alors veuillez l'utiliser.
J'ai essayé de trouver la matrice affine dans l'alignement de l'image (correspondance des points caractéristiques) en utilisant la transformation affine
Un moyen simple de visualiser le temps pris en Python et un moyen plus intelligent de l'améliorer
L'utilisation du japonais pour les noms de dossier et les noms de bloc-notes dans Databricks peut poser problème
Comment déterminer l'existence d'un élément sélénium en Python
Comment connaître la structure interne d'un objet en Python
Comment vérifier la taille de la mémoire d'une variable en Python
Comment vérifier la taille de la mémoire d'un dictionnaire en Python
Comment afficher le résultat de sortie de la commande man Linux dans un fichier
Comment utiliser l'apprentissage automatique pour le travail? 01_ Comprendre l'objectif de l'apprentissage automatique
Comment prendre une capture d'écran de l'écran Chrome (l'empêcher de se couper au milieu)
[Python] Qu'est-ce qu'une tranche? Une explication facile à comprendre de son utilisation avec un exemple concret
Comment obtenir la valeur en pixels du point à partir de l'image satellite en spécifiant la latitude et la longitude
[Python] Le rôle de l'astérisque devant la variable. Divisez la valeur d'entrée et affectez-la à une variable
[Python] Comment utiliser l'instruction for. Une méthode d'extraction en spécifiant une plage ou des conditions.
Apprenez le flux de l'estimation bayésienne et comment utiliser Pystan grâce à un modèle de régression simple
Je souhaite extraire les informations d'étiquette (titre et artiste) d'un fichier de musique (flac, wav).
Python démarré: échangez le tableau de valeurs obtenu dans le résultat SQL vers le type de liste et utilisez-le dans IN d'une autre requête
De l'introduction de l'API GoogleCloudPlatform Natural Language à son utilisation
Comment diviser et enregistrer un DataFrame
[Python / Jupyter] Traduisez le commentaire du programme copié dans le presse-papiers et insérez-le dans une nouvelle cellule.
J'ai créé un script POST pour créer un problème sur Github et l'enregistrer dans le projet
Comment envoyer une image visualisée des données créées en Python à Typetalk
Comment spécifier un fichier .ui dans la boîte de dialogue / interface graphique du widget dans PySide
Comment mettre un numéro de ligne au début d'un fichier CSV
Comment rendre le nom du conteneur accessible dans Docker en tant que sous-domaine
Ouvrez un fichier Excel en Python et coloriez la carte du Japon
J'ai fait un programme pour vérifier la taille d'un fichier avec Python
Comment copier et coller le contenu d'une feuille au format JSON avec une feuille de calcul Google (en utilisant Google Colab)
[python] Envoyez l'image capturée de la caméra Web au serveur et enregistrez-la
Comment utiliser is et == en Python
Comment saisir une chaîne de caractères en Python et la sortir telle quelle ou dans la direction opposée.
L'arbre.plot_tree de scikit-learn était très simple et pratique, j'ai donc essayé de résumer comment l'utiliser facilement.
Une histoire sur un ingénieur qui a remarqué l'émo de la cryptographie et tente de l'implémenter en Python
GAE --Avec Python, faites pivoter l'image en fonction des informations de rotation d'EXIF et importez-la dans Cloud Storage.
Je pensais qu'il serait lent d'utiliser l'instruction for dans NumPy, mais ce n'était pas le cas.
Différentes façons de lire la dernière ligne d'un fichier csv en Python
Comment passer le résultat de l'exécution d'une commande shell dans une liste en Python
Créer en Python sans fichier image factice dans Django et tester le téléchargement de l'image
Comment mentionner un groupe d'utilisateurs avec une notification de mou, comment vérifier l'ID d'un groupe d'utilisateurs
Utilisez libsixel pour générer Sixel en Python et générer le graphe Matplotlib vers le terminal.
Je veux écrire un élément dans un fichier avec numpy et le vérifier.
[Python] Combiner des listes contenant des nombres en chaînes et les écrire dans un fichier de sortie