[PYTHON] [Vérification] Essayez d'aligner le groupe de points avec la fonction d'optimisation de pytorch Partie 1

introduction

J'ai récemment appris le pytorch alors je vais jouer avec.

Tout ce que vous avez à faire est d'aligner les points.

Le but est que l'icp ait une image personnelle qui a tendance à tomber dans une solution locale, La fonction d'optimisation de pointe de pytorch ne fonctionne-t-elle pas plutôt bien? Je vais l'essayer avec l'attente moelleuse.

Le flux est le suivant.

pour chaque point du groupe de points B
   1.Matrice de transformation$P = [R|t]$Est défini.
L'alignement est effectué en optimisant ce paramètre.
   2.Calculez le voisinage le plus proche du groupe de points et obtenez l'ensemble des points les plus proches.
   3.Matrice de transformation$P$Les points du groupe de points B auxquels
Les points les plus proches du groupe de points A, ces deux, sont évalués par la fonction de perte.
   4.Processus d'optimisation
Matrice de transformation optimisée$P$Appliquer et recommencer à partir de 1

Vérifiez avec le flux suivant.

1.Préparez deux groupes de points identiques et déplacez uniquement (ajustement des paramètres 3D)
2.Préparez deux groupes de points identiques et effectuez uniquement une rotation (ajustement des paramètres à 9 dimensions)
3.Préparer deux groupes de points identiques et faire pivoter / déplacer (réglage des paramètres en 12 dimensions)
3.Préparer deux groupes de points différents et faire pivoter / déplacer (réglage des paramètres en 12 dimensions)
3.Ajoutez du bruit de l'autre côté, préparez deux groupes de points différents et faites pivoter / déplacer (réglage des paramètres en 12 dimensions)

résultat

J'ai écrit cela, mais j'ai échoué au premier stade. Je ne suis pas encore habitué au pytorch, alors peut-être qu'il manque quelque chose.

tetst.py


    import copy
    import numpy as np
    import open3d as o3d
    import random
    import math
    import torch.nn as nn
    import torch.nn.functional as F
    import torch
    import torch.optim as optim
    import matplotlib.pyplot as plt

    epoch = 1000

    def getPLYfromNumpy(nplist):
        pcd = o3d.geometry.PointCloud()
        pcd.points = o3d.utility.Vector3dVector(nplist)
        return pcd


    def write_point_cloud(path, pcl):
        assert o3d.io.write_point_cloud(path, pcl), "write pcl error : " + path


    def read_point_cloud(path):
        pcl = o3d.io.read_point_cloud(path)
        if len(pcl.points) == 0: assert False, "load pcl error : " + path
        return pcl

    def Register_EachPoint_RT(pclA, pclB,testP,criterion,optimizer):
        history = {
            'train_loss': [],
            'test_acc': [],
        }

        transP = torch.tensor(
            [[1.0, 0.0, 0.0, 0.0], [0.0, 1.0, 0.0, 0.0], [0.0, 0.0, 1.0, 0.0], [0.0, 0.0, 0.0, 1.0]],
            requires_grad=True)
        params = [transP]
        optimizer = optimizer(params)

        kd_tree_A = o3d.geometry.KDTreeFlann(pclA)
        cnt = 0
        #Essayez-le en points
        for j in range(epoch):
            for didx in range(len(pclB.points)):
                cnt += 1
                optimizer.zero_grad()
                #Calcul le plus proche
                [_, Aidx1, _] = kd_tree_A.search_knn_vector_3d(pclB.points[didx], 1)
                ptA_sample = pclA.points[Aidx1[0]]
                ptB_sample = pclB.points[didx]

                #Coordonnées cachées
                ptA_sample = np.array([ptA_sample[0], ptA_sample[1], ptA_sample[2], 1])
                ptB_sample = np.array([ptB_sample[0], ptB_sample[1], ptB_sample[2], 1])
                ptA_sample = ptA_sample.reshape(4, 1)
                ptB_sample = ptB_sample.reshape(4, 1)

                A_tor = torch.tensor(ptA_sample.tolist(), requires_grad=False)
                B_tor = torch.tensor(ptB_sample.tolist(), requires_grad=False)
                answer = A_tor
                output = torch.mm(transP, B_tor)

                loss = criterion(answer, output)

                loss.backward()
                optimizer.step()

                # print( j, cnt, " :Erreur= ", loss.item(),"\n",transP)
                ls = np.linalg.norm(testP - transP.to('cpu').detach().numpy().copy())

                history['train_loss'].append(loss)
                history['test_acc'].append(ls)

        print(" :Erreur= ", loss.item(),"\t Erreur avec la matrice de conversion correcte= ",ls)

        plt.figure()
        plt.plot(range(1, cnt + 1), history['train_loss'], label='train_loss')
        plt.xlabel('train_loss')
        plt.legend()
        plt.savefig('train_loss.png')

        plt.figure()
        plt.plot(range(1, cnt + 1), history['test_acc'], label='test_acc')
        plt.xlabel('test_acc')
        plt.legend()
        plt.savefig('test_acc.png')

        return transP

    def Register_EachPoint_T(pclA, pclB,testP,criterion,optimizer):
        history = {
            'train_loss': [],
            'test_acc': [],
        }

        transP = torch.tensor([[0.0], [0.0], [0.0]],requires_grad=True)
        params = [transP]
        optimizer = optimizer(params)

        kd_tree_A = o3d.geometry.KDTreeFlann(pclA)
        cnt = 0

        #Essayez-le en points
        for j in range(epoch):
            for didx in range(len(pclB.points)):
                cnt += 1
                optimizer.zero_grad()
                #Obtenez les points du groupe de points A les plus proches de chaque point du groupe de points B
                [_, Aidx1, _] = kd_tree_A.search_knn_vector_3d(pclB.points[didx], 1)
                ptA_sample = pclA.points[Aidx1[0]]
                ptB_sample = pclB.points[didx]

                #Coordonnées cachées
                ptA_sample = np.array([ptA_sample[0], ptA_sample[1], ptA_sample[2]])
                ptB_sample = np.array([ptB_sample[0], ptB_sample[1], ptB_sample[2]])
                ptA_sample = ptA_sample.reshape(3, 1)
                ptB_sample = ptB_sample.reshape(3, 1)

                #Convertir chaque point en Tensor
                A_tor = torch.tensor(ptA_sample.tolist(), requires_grad=False)
                B_tor = torch.tensor(ptB_sample.tolist(), requires_grad=False)

                #Ajustez le groupe de points B pour correspondre au groupe de points A.
                answer = A_tor
                output = (B_tor + transP)

                #Calcul des pertes->optimisation
                loss = criterion(answer, output)
                loss.backward()
                optimizer.step()

                #Comparaison avec la bonne matrice de conversion. (0 est souhaitable)
                ls = np.linalg.norm(testP - transP.to('cpu').detach().numpy().copy())

                history['train_loss'].append(loss)
                history['test_acc'].append(ls)

            print(" :Erreur= ", loss.item(), "\t Erreur avec la matrice de conversion correcte= ", ls)

            #Refléter le résultat de l'ajustement->Calcul du voisin le plus proche à nouveau dans la boucle suivante
            nptransP = transP.to('cpu').detach().numpy().copy().reshape(1,3)
            pclB = getPLYfromNumpy(pclB.points + nptransP)


        plt.figure()
        plt.plot(range(1, cnt + 1), history['train_loss'], label='train_loss')
        plt.xlabel('train_loss')
        plt.legend()
        plt.savefig('train_loss.png')

        plt.figure()
        plt.plot(range(1, cnt + 1), history['test_acc'], label='test_acc')
        plt.xlabel('test_acc')
        plt.legend()
        plt.savefig('test_acc.png')

        return transP

    POINT_NUM = 1024

    # http://graphics.stanford.edu/data/3Dscanrep/
    pclA = read_point_cloud("bun000.ply")
    A = np.array(pclA.points)
    A = np.array(random.sample(A.tolist(), POINT_NUM))

    #Un groupe de points avec un niveau de difficulté légèrement plus élevé. Peut-être que cela ne peut pas encore être fait ...
    # pclB = read_point_cloud("bun045.ply")
    # B = np.array(pclB.points)
    # B = np.array(random.sample(B.tolist(), POINT_NUM))
    # #Ajoute du bruit
    # B += np.random.randn(POINT_NUM, 3) * 0.005
    # #Accorder le désordre (dans l'ordre) des groupes de points
    # np.random.shuffle(B)
    # pclB_sample = getPLYfromNumpy(B)

    pclA_sample = getPLYfromNumpy(A)
    T_Projection = np.array([[1, 0, 0, 0.5],
                       [0, 1, 0, 0],
                       [0, 0, 1, 0],
                       [0, 0, 0, 1]])
    T_translation = np.array([[T_Projection[0][3]], [T_Projection[1][3]], [T_Projection[2][3]]])
    pclA_trans_sample = getPLYfromNumpy(A).transform(T_Projection)

    write_point_cloud("A_before.ply", pclA_sample)
    write_point_cloud("A_rot_before.ply", pclA_trans_sample)


    def testEstimateT(pclA_sample,pclA_trans_sample,T_translation):
        optimizer = optim.Adam
        # MSELoss
        transP = Register_EachPoint_T(pclA_sample, pclA_trans_sample, T_translation, nn.MSELoss(),optimizer)
        T_res = np.array([[1, 0, 0, transP[0]],
                          [0, 1, 0, transP[1]],
                          [0, 0, 1, transP[2]],
                          [0, 0, 0, 1]])
        pclA_res = copy.copy(pclA_trans_sample)
        pclA_res = pclA_res.transform(T_res)
        write_point_cloud("TOnlytest_A_rot_after_MSELoss.ply", pclA_res)

        # # L1Loss
        # transP = Register_EachPoint_T(pclA_sample, pclA_trans_sample, T_translation, nn.L1Loss(),optimizer)
        # T_res = np.array([[1, 0, 0, transP[0]],
        #                   [0, 1, 0, transP[1]],
        #                   [0, 0, 1, transP[2]],
        #                   [0, 0, 0, 1]])
        # pclA_res = copy.copy(pclA_trans_sample)
        # pclA_res = pclA_res.transform(T_res)
        # write_point_cloud("TOnlytest_A_rot_after_L1Loss.ply", pclA_res)

    def testEstimateRT(pclA_sample,pclA_trans_sample,T_Projection):
        optimizer = optim.Adam
        # MSELoss
        transP = Register_EachPoint_RT(pclA_sample, pclA_trans_sample, T_Projection, nn.MSELoss(),optimizer)
        transP = transP.to('cpu').detach().numpy().copy()
        pclA_res = copy.copy(pclA_trans_sample)
        pclA_res = pclA_res.transform(transP)
        write_point_cloud("RTtest_A_rot_after_MSELoss.ply", pclA_res)

    testEstimateT(pclA_sample, pclA_trans_sample, T_translation)
    # testEstimateRT(pclA_sample, pclA_trans_sample, T_Projection)


    exit()

Voyons le résultat de sortie de la fonction de perte. En regardant cela seul, il semble qu'il converge vers 0 en un clin d'œil. train_loss.png

Et ceci est une comparaison de la matrice de conversion sortie par optimisation et de la matrice de conversion de la bonne réponse. test_acc.png

... Je pense que j'ai baissé un peu au début, mais j'ai toujours faim. C'est une grosse erreur de 0,5. J'ai également sorti un groupe de points, mais je vais l'omettre car c'était seulement un peu plus proche.

Sommaire

Il n'y a pas de valeur aberrante et il n'y a que 3 dimensions, mais pourquoi ... J'ai l'impression que je fais simplement une erreur en utilisant Pytorch. Si vous le savez, veuillez me contacter.

Ensuite, nous étudierons PointNet LK, qui est une extension du T-net de PointNet. https://github.com/wentaoyuan/it-net https://www.slideshare.net/naoyachiba18/pointnetlk-robust-efficient-point-cloud-registration-using-pointnet-167874587

Recommended Posts

[Vérification] Essayez d'aligner le groupe de points avec la fonction d'optimisation de pytorch Partie 1
Essayez l'optimisation des fonctions avec Optuna
Essayez d'obtenir la liste des fonctions du paquet Python> os
Essayez d'automatiser le fonctionnement des périphériques réseau avec Python
Essayez d'extraire les caractéristiques des données de capteur avec CNN
J'ai essayé d'afficher les données du groupe de points DB de la préfecture de Shizuoka avec Vue + Leaflet
[Note] Essayons de prédire la quantité d'électricité utilisée! (Partie 1)
Trouvez la valeur optimale de la fonction à l'aide d'un algorithme génétique (partie 2)
Essayez de résoudre le problème N Queen avec SA de PyQUBO
Essayez de résoudre le problème de minimisation des fonctions en utilisant l'optimisation des groupes de particules
Alignez la taille de la barre de couleurs avec matplotlib
Comment couper la partie inférieure droite de l'image avec Python OpenCV
Essayez d'imaginer les données d'élévation du National Land Research Institute avec Python
Essayez de ne faire réagir que le carbone en bout de chaîne avec SMARTS
Essayez de séparer l'arrière-plan et l'objet en mouvement de la vidéo avec OpenCV
Essayez de détecter un objet avec RaspberryPi ~ Partie 1: Comparaison de la vitesse de détection ~
Essayez d'installer uniquement la partie principale d'Ubuntu
Trouver la main de "Millijan" par l'optimisation des combinaisons
Essayez de résoudre le diagramme homme-machine avec Python
Comment essayer l'algorithme des amis d'amis avec pyfof
Modifiez le point décimal de la journalisation de, à.
Histoire d'essayer d'utiliser Tensorboard avec Pytorch
Essayez de simuler le mouvement du système solaire
Diverses méthodes pour créer numériquement la fonction inverse d'une certaine fonction Partie 1 Régression polynomiale
Essayez de créer une table d'enregistrement de bataille avec matplotlib à partir des données de "Schedule-kun"
[Django] Essayons de clarifier la partie de Django qui était en quelque sorte à travers le test
C'est Noël, donc je vais essayer de dessiner la généalogie de Jésus-Christ avec Cabocha
[Cloud 9] Essayez de créer un environnement avec django 1.11 de Python 3.4 sans même comprendre 1 mm
J'ai essayé d'entraîner la fonction péché avec chainer
Essayez de résoudre le livre des défis de programmation avec python3
Ajoutez des informations au bas de la figure avec Matplotlib
[Introduction à Python] Comment itérer avec la fonction range?
Essayez de résoudre les problèmes / problèmes du "programmeur matriciel" (Chapitre 1)
Essayez de résoudre le problème d'affectation du médecin de formation avec Python
Essayez d'estimer le nombre de likes sur Twitter
[Neo4J] ④ Essayez de gérer la structure du graphe avec Cypher
Préparation de l'environnement d'exécution de PyTorch avec Docker Novembre 2019
J'ai essayé d'effacer la partie négative de Meros
Comment frapper le document de Magic Function (Line Magic)
Comment connaître le nombre de GPU de python ~ Remarques sur l'utilisation du multitraitement avec pytorch ~
Essayez d'importer dans la base de données en manipulant ShapeFile d'informations numériques sur les terres nationales avec Python
Essayez de visualiser les nutriments des flocons de maïs que le champion de M-1 Milkboy a dit avec Python
Nuage de points avec du poivre
[Python] Modifier le contrôle du cache des objets téléchargés sur Cloud Storage
Essayez de gratter les données COVID-19 Tokyo avec Python
Essayez d'évaluer les performances du modèle d'apprentissage automatique / de régression
Acquisition d'un groupe de points 3D avec Pepper de Softbank (Choregraphe, Python)
Essayez de jouer avec l'uprobe qui prend directement en charge Systemtap
Sauvegardez la sortie de GAN une par une ~ Avec l'implémentation de GAN par PyTorch ~
J'ai essayé de trouver la moyenne de plusieurs colonnes avec TensorFlow
Essayez d'évaluer les performances du modèle d'apprentissage automatique / de classification
J'ai fait une fonction pour vérifier le modèle de DCGAN
[Part.2] Exploration avec Python! Cliquez sur la page Web pour vous déplacer!
Paramètres pour entrer et déboguer le contenu de la bibliothèque avec VS Code
Essayez d'améliorer la précision de l'estimation du nombre de Twitter
Essayez de résoudre les problèmes / problèmes du "programmeur matriciel" (fonction du chapitre 0)
Comment exécuter automatiquement la fonction d'exportation de GCP Datastore
Tentative d'ajuster automatiquement la vitesse des vidéos accélérées (partie 2)
J'ai essayé de combattre le minimum local de la fonction Goldstein-Price