Correspondance de profil dans un nuage de points

14

Un nuage de points est généré à l'aide d'une fonction aléatoire uniforme pour (x,y,z). Comme le montre la figure suivante, un plan ( profil ) d' intersection plat est à l'étude qui correspond au meilleur (même s'il n'est pas exact) un profil cible, c'est-à-dire donné dans le coin inférieur gauche. La question est donc:

1- Comment trouver une telle correspondance de donné target 2D point mapen point cloudconsidérant les notes / conditions suivantes?
2- Quelles sont alors les coordonnées / orientations / degrés de similitude etc?

Remarque 1: Le profil d'intérêt peut être n'importe où avec une rotation le long des axes et peut également avoir une forme différente, par exemple un triangle, un rectangle, un quadrilatère, etc., selon son emplacement et son orientation. Lors de la démonstration suivante, seul un rectangle simple est affiché.

Remarque 2: Une valeur de tolérance peut être considérée comme la distance des points par rapport au profil. Pour le voir la figure suivante suppose une tolérance de 0.01temps la plus petite dimension (~1)donc tol=0.01. Donc, si nous supprimons le reste et projetons tous les points restants sur le plan du profil étudié, nous serons en mesure de vérifier sa similitude avec le profil cible.

Remarque 3: Un sujet connexe peut être trouvé à la reconnaissance des formes de points .

entrez la description de l'image ici

Développeur
la source
@Developer Off topic mais quel logiciel utilisez-vous pour générer ces tracés?
Spacey
1
@Mohammad J'utilise Python+ MatPlotLibpour faire mes recherches et générer les graphiques etc.
Développeur
@Developer Fantastic - c'est via Python, mais que signifient-ils «shell Python ala Matlab»?
Spacey
Comment sont stockés les nuages ​​de points? Comme un ensemble de coordonnées pour le centre de chaque point ou comme un ensemble de données volumétriques qui a des valeurs non nulles dans les coordonnées autour des points?
endolith
@endolith Tous les points ont des coordonnées associées comme P:{x,y,z}. Ce sont en effet des points sans dimension. Cependant, avec une certaine approximation, ils pourraient être discrétisés à une dimension d'un pixel sous forme de tableaux 3D. Ils peuvent également incorporer d'autres attributs (tels que des poids, etc.) aux coordonnées.
Développeur

Réponses:

4

Cela va toujours nécessiter beaucoup de calculs, surtout si vous souhaitez traiter jusqu'à 2000 points. Je suis sûr qu'il existe déjà des solutions hautement optimisées pour ce type de correspondance de modèles, mais vous devez comprendre comment cela s'appelle afin de les trouver.

Puisque vous parlez d'un nuage de points (données clairsemées) au lieu d'une image, ma méthode de corrélation croisée ne s'applique pas vraiment (et serait encore pire sur le plan informatique). Quelque chose comme RANSAC trouve probablement une correspondance rapidement, mais je n'en sais pas grand-chose.

Ma tentative de solution:

Hypothèses:

  • Vous voulez trouver la meilleure correspondance, pas seulement une correspondance lâche ou "probablement correcte"
  • La correspondance aura une petite quantité d'erreur due au bruit dans la mesure ou le calcul
  • Les points sources sont coplanaires
  • Tous les points source doivent exister dans la cible (= tout point sans correspondance est une incompatibilité pour tout le profil)

Vous devriez donc pouvoir prendre beaucoup de raccourcis en disqualifiant les choses et en réduisant le temps de calcul. En bref:

  1. choisir trois points de la source
  2. rechercher dans les points cibles, trouver des ensembles de 3 points de même forme
  3. lorsqu'une correspondance de 3 points est trouvée, vérifiez tous les autres points dans le plan qu'ils définissent pour voir s'ils correspondent étroitement
  4. si plus d'une correspondance de tous les points est trouvée, choisissez celle avec la plus petite somme d'erreur de distances 3D

Plus détaillé:

pick a point from the source for testing s1 = (x1, y1)
Find nearest point in source s2 = (x2, y2)
d12 = (x1-x2)^2 + (y1-y2)^2
Find second nearest point in source s3 = (x3, y3)
d13 = (x1-x3)^2 + (y1-y3)^2
d23 = (x2-x3)^2 + (y2-y3)^2

for all (x,y,z) test points t1 in target:
    # imagine s1 and t1 are coincident
    for all other points t2 in target:
        if distance from test point > d12:    
            break out of loop and try another t2 point
        if distance ≈ d12:
            # imagine source is now rotated so that s1 and s2 are collinear with t1 and t2
            for all other points t3 in target:
                if distance from t1 > d13 or from t2 > d23:
                    break and try another t3
                if distance from t1 ≈ d13 and from t2 ≈ d23:
                    # Now you've found matching triangles in source and target
                    # align source so that s1, s2, s3 are coplanar with t1, t2, t3
                    project all source points onto this target plane 
                    for all other points in source:
                        find nearest point in target
                        measure distance from source point to target point
                        if it's not within a threshold:
                            break and try a new t3
                        else:
                            sum errors of all matched points for this configuration (defined by t1, t2, t3)

Quelle que soit la configuration qui présente le moins d'erreur quadratique pour tous les autres points, c'est la meilleure correspondance

Étant donné que nous travaillons avec 3 points de test voisins les plus proches, la correspondance des points cibles peut être simplifiée en vérifiant s'ils se trouvent dans un certain rayon. Si vous recherchez un rayon de 1 à partir de (0, 0), par exemple, nous pouvons disqualifier (2, 0) sur la base de x1 - x2, sans calculer la distance euclidienne réelle, pour l'accélérer un peu. Cela suppose que la soustraction est plus rapide que la multiplication. Il existe également des recherches optimisées basées sur un rayon fixe plus arbitraire .

function is_closer_than(x1, y1, z1, x2, y2, z2, distance):
    if abs(x1 - x2) or abs(y1 - y2) or abs(z1 - z2) > distance:
        return False
    return (x1 - x2)^2 + (y1 - y2)^2 + (z1 - z2)^2 > distance^2 # sqrt is slow

=(X1-X2)2+(y1-y2)2+(z1-z2)2

Le temps de calcul minimum serait si aucune correspondance à 2 points n'est trouvée. S'il y a 2000 points dans la cible, ce serait des calculs de distance de 2000 * 2000, bien que beaucoup soient disqualifiés par une soustraction, et les résultats des calculs précédents pourraient être stockés de sorte que vous n'avez qu'à faire = 1999000.(20002)

En fait, puisque vous devrez de toute façon calculer tous ces éléments, que vous trouviez des correspondances ou non, et puisque vous ne vous souciez que des voisins les plus proches pour cette étape, si vous avez la mémoire, il est probablement préférable de pré-calculer ces valeurs à l'aide d'un algorithme optimisé . Quelque chose comme une triangulation de Delaunay ou Pitteway , où chaque point de la cible est connecté à ses voisins les plus proches. Stockez-les dans un tableau, puis recherchez-les pour chaque point lorsque vous essayez d'ajuster le triangle source à l'un des triangles cibles.

Il y a beaucoup de calculs impliqués, mais cela devrait être relativement rapide car il ne fonctionne que sur les données, ce qui est rare, au lieu de multiplier beaucoup de zéros sans signification, comme une corrélation croisée de données volumétriques impliquerait. Cette même idée fonctionnerait pour le cas 2D si vous trouviez d'abord les centres des points et les stockiez sous la forme d'un ensemble de coordonnées.

endolith
la source
1
La première partie de votre réponse est en fait une méthode de force brute recherchant des points proches (en comptant par rapport à un seuil) autour de tous les plans possibles à travers le nuage de points. Il est extrêmement intensif en calcul, par exemple, pour seulement 2000 points, un nombre de 2 662 668 000 000 (formule) de calcul de distance sera nécessaire!
Développeur
@Developer: Oui, cela va prendre beaucoup de calculs, surtout si vous avez des milliers de points. Oui, pour 2000 points, si vous ne trouvez aucun avion, vous finirez par faire 2 658 673 998 000 calculs. Je suppose que vous voulez trouver des avions, mais, ce qui réduirait le temps car il arrête dès qu'il a trouvé assez de points. Mais de toute façon, j'y pensais et j'ai probablement une meilleure idée, et je vais changer la réponse.
endolith
1
Vous avez absolument tout à fait raison. Juste pour ajouter que les critères d'arrêt ne peuvent pas s'appliquer même après avoir trouvé un avion approprié alors qu'il pourrait y avoir une bien meilleure correspondance, donc tous les avions possibles doivent être vérifiés. J'ai déjà mis en œuvre cette idée et j'ai découvert que même avec l'aide de Fortrannombres supérieurs aux 500points, il serait impossible d'avoir des expériences avec PC.
Développeur
2

J'ajouterais une description @ mirror2image sur la solution alternative à côté de RANSAC, vous pouvez considérer l'algorithme ICP (point le plus proche itératif), une description peut être trouvée ici !

Je pense que le prochain défi dans l'utilisation de cet ICP est de définir votre propre fonction de coût et la pose de départ du plan cible par rapport aux données de point de nuage 3D. Une approche pratique consiste à introduire du bruit aléatoire dans les données pendant l'itération pour éviter de converger vers les faux minima. C'est la partie heuristique que je suppose que vous devez concevoir.

Mise à jour:

Les étapes sous forme simplifiée sont:

  1. Trouvez le point le plus proche pour chaque point d'entrée.
  2. Calculez la transformation de l'entrée vers la cible, puis déplacez les points d'entrée à l'aide de la transformation.
  3. Calculez la fonction de similitude (par exemple, la distance pour chaque point d'entrée par rapport à son point cible de paire correspondant).
  4. Vérifiez l'état d'arrêt.

Répétez l'étape 1-4.

Il y a une bibliothèque disponible que vous pouvez considérer ici ! (Je ne l'ai pas encore essayé), il y a une section sur la partie enregistrement (y compris d'autres méthodes).

kuskus
la source
Merci pour le lien et la suggestion. Ces idées utiles nous aident toujours en tant que chercheurs débutants à apprendre des choses plus rapidement. J'apprécie toujours plus d'explications.
Développeur