fuse_object_model_3dT_fuse_object_model_3dFuseObjectModel3dFuseObjectModel3d (Operator)

Name

fuse_object_model_3dT_fuse_object_model_3dFuseObjectModel3dFuseObjectModel3d — Fusionieren von 3D-Objektmodellen.

Signatur

fuse_object_model_3d( : : ObjectModel3D, BoundingBox, Resolution, SurfaceTolerance, MinThickness, Smoothing, NormalDirection, GenParamName, GenParamValue : ObjectModel3DFusion)

Herror T_fuse_object_model_3d(const Htuple ObjectModel3D, const Htuple BoundingBox, const Htuple Resolution, const Htuple SurfaceTolerance, const Htuple MinThickness, const Htuple Smoothing, const Htuple NormalDirection, const Htuple GenParamName, const Htuple GenParamValue, Htuple* ObjectModel3DFusion)

void FuseObjectModel3d(const HTuple& ObjectModel3D, const HTuple& BoundingBox, const HTuple& Resolution, const HTuple& SurfaceTolerance, const HTuple& MinThickness, const HTuple& Smoothing, const HTuple& NormalDirection, const HTuple& GenParamName, const HTuple& GenParamValue, HTuple* ObjectModel3DFusion)

static HObjectModel3D HObjectModel3D::FuseObjectModel3d(const HObjectModel3DArray& ObjectModel3D, const HTuple& BoundingBox, const HTuple& Resolution, const HTuple& SurfaceTolerance, const HTuple& MinThickness, const HTuple& Smoothing, const HTuple& NormalDirection, const HTuple& GenParamName, const HTuple& GenParamValue)

HObjectModel3D HObjectModel3D::FuseObjectModel3d(const HTuple& BoundingBox, double Resolution, double SurfaceTolerance, double MinThickness, double Smoothing, const HString& NormalDirection, const HTuple& GenParamName, const HTuple& GenParamValue) const

HObjectModel3D HObjectModel3D::FuseObjectModel3d(const HTuple& BoundingBox, double Resolution, double SurfaceTolerance, double MinThickness, double Smoothing, const char* NormalDirection, const HTuple& GenParamName, const HTuple& GenParamValue) const

HObjectModel3D HObjectModel3D::FuseObjectModel3d(const HTuple& BoundingBox, double Resolution, double SurfaceTolerance, double MinThickness, double Smoothing, const wchar_t* NormalDirection, const HTuple& GenParamName, const HTuple& GenParamValue) const   (Nur Windows)

static void HOperatorSet.FuseObjectModel3d(HTuple objectModel3D, HTuple boundingBox, HTuple resolution, HTuple surfaceTolerance, HTuple minThickness, HTuple smoothing, HTuple normalDirection, HTuple genParamName, HTuple genParamValue, out HTuple objectModel3DFusion)

static HObjectModel3D HObjectModel3D.FuseObjectModel3d(HObjectModel3D[] objectModel3D, HTuple boundingBox, HTuple resolution, HTuple surfaceTolerance, HTuple minThickness, HTuple smoothing, HTuple normalDirection, HTuple genParamName, HTuple genParamValue)

HObjectModel3D HObjectModel3D.FuseObjectModel3d(HTuple boundingBox, double resolution, double surfaceTolerance, double minThickness, double smoothing, string normalDirection, HTuple genParamName, HTuple genParamValue)

Beschreibung

fuse_object_model_3dfuse_object_model_3dFuseObjectModel3dFuseObjectModel3dFuseObjectModel3d fusioniert mehrere Punktwolken, welche die Oberfläche eines Objekts repräsentieren, zu einer wasserdichten Oberfläche ObjectModel3DFusionObjectModel3DFusionObjectModel3DFusionObjectModel3DFusionobjectModel3DFusion. Der Operator vereinfacht die Nachverarbeitung von Punktwolken, welche bereits im selben Koordinatensystem erfasst sind. Insbesondere können folgende Prozesse oft einfach und mit hoher Qualität abgewickelt werden: Vereinigung, Unterdrückung von Ausreißern, Kompromiss aus Glättung und Kantenerhaltung, äquidistantes Subsampling, Löcher füllen, Vermaschung der resultierenden Oberfläche. Der Operator fuse_object_model_3dfuse_object_model_3dFuseObjectModel3dFuseObjectModel3dFuseObjectModel3d hat allerdings eine relativ lange Rechenzeit.

Sollen Punktwolken fusioniert werden, welche über Stereo-Rekonstruktion aufgenommen wurden, sollte stattdessen reconstruct_surface_stereoreconstruct_surface_stereoReconstructSurfaceStereoReconstructSurfaceStereoReconstructSurfaceStereo verwendet werden.

Ablauf

  1. Aufnahme der Punktwolken; diese in ein einheitliches Koordinatensystem bringen, z.B. mittels register_object_model_3d_pairregister_object_model_3d_pairRegisterObjectModel3dPairRegisterObjectModel3dPairRegisterObjectModel3dPair und register_object_model_3d_globalregister_object_model_3d_globalRegisterObjectModel3dGlobalRegisterObjectModel3dGlobalRegisterObjectModel3dGlobal.

  2. Berechnen der Dreiecke oder Punktnormalen für die Punktwolken mittels triangulate_object_model_3dtriangulate_object_model_3dTriangulateObjectModel3dTriangulateObjectModel3dTriangulateObjectModel3d oder surface_normals_object_model_3dsurface_normals_object_model_3dSurfaceNormalsObjectModel3dSurfaceNormalsObjectModel3dSurfaceNormalsObjectModel3d, sofern diese nicht bereits vorhanden sind. Die Triangulierung ist geeigneter, falls die Oberflächen viele Ausreißer oder zu schließende Löcher haben. Ansonsten, im Falle von glatten Oberflächen, kann man mit Punktnormalen arbeiten.

  3. Inspizieren der Normalen des Eingabe-Modells mittels visualize_object_model_3d mit der Option GenParamNameGenParamNameGenParamNameGenParamNamegenParamName 'disp_normals' oder dev_inspect_ctrl. Die Punkt- oder Dreiecksnormalen müssen konsistent entweder nach innen oder außen gerichtet sein. Der Parameter NormalDirectionNormalDirectionNormalDirectionNormalDirectionnormalDirection muss dann entsprechend auf 'inwards'"inwards""inwards""inwards""inwards" oder 'outwards'"outwards""outwards""outwards""outwards" gesetzt werden.

  4. Festlegen des umschließenden Quaders über den Parameter BoundingBoxBoundingBoxBoundingBoxBoundingBoxboundingBox. Für eine erste Näherung des umschließenden Quaders BoundingBoxBoundingBoxBoundingBoxBoundingBoxboundingBox kann get_object_model_3d_paramsget_object_model_3d_paramsGetObjectModel3dParamsGetObjectModel3dParamsGetObjectModel3dParams verwendet werden, mit GenParamNameGenParamNameGenParamNameGenParamNamegenParamName gesetzt auf 'bounding_box1'.

  5. Die Werte für die initialen Parameter kann man wie folgt abschätzen: Einen groben Wert für ResolutionResolutionResolutionResolutionresolution (z.B. 1/100 der Raumdiagonalen des umschließenden Quaders BoundingBoxBoundingBoxBoundingBoxBoundingBoxboundingBox), SurfaceToleranceSurfaceToleranceSurfaceToleranceSurfaceTolerancesurfaceTolerance etwas größer (z.B. 5*ResolutionResolutionResolutionResolutionresolution), MinThicknessMinThicknessMinThicknessMinThicknessminThickness als minimale Dicke des Objekts (sollte die Eingabe-Punktwolke das Objekt nur von einer Seite aus darstellen, wird empfohlen, den Wert sehr hoch zu setzen, damit das Objekt erst durch den umschließenden Quader BoundingBoxBoundingBoxBoundingBoxBoundingBoxboundingBox abgeschnitten wird) und SmoothingSmoothingSmoothingSmoothingsmoothing mit Wert 1.0.

  6. Ausführen des Operators fuse_object_model_3dfuse_object_model_3dFuseObjectModel3dFuseObjectModel3dFuseObjectModel3d und nachjustieren der Parameterwerte zur Verbesserung des Ergebnisses bezüglich Qualität und Rechenzeit, siehe auch unten. Zur Vermeidung langer Rechenzeiten ist eine Auflösung ResolutionResolutionResolutionResolutionresolution empfohlen, die gerade noch ausreichend ist, um Objektdetails erkennen zu können, während die anderen Parameter eingestellt werden. Zur Optimierung sollten auch die zusätzlichen Parameter von GenParamNameGenParamNameGenParamNameGenParamNamegenParamName in Erwägung gezogen werden.

Parameterbeschreibung

In dem HDevelop-Beispiel fuse_object_model_3d_workflow wird gezeigt, wie die hier aufgelisteten Parameter für eine bestimmte Anwendung optimiert werden können.

Die Eingabe-Punktwolken ObjectModel3DObjectModel3DObjectModel3DObjectModel3DobjectModel3D müssen in einem gemeinsamen Koordinatensystem sein und stellen die initiale Oberfläche dar. Des Weiteren müssen diese Punktwolken Dreiecke oder Punktnormalen beinhalten. Sollten beide Attribute vorhanden sein, werden, aufgrund der Geschwindigkeitsvorteile, als Standardeinstellung Punktnormalen verwendet. Wenn die Verwendung von Dreiecken gewünscht ist, müssen die Dreiecke und Punkte mittels copy_object_model_3dcopy_object_model_3dCopyObjectModel3dCopyObjectModel3dCopyObjectModel3d in ein neues Objektmodell überführt werden. Mit Oberflächen, die viele Ausreißer oder zu füllende Löcher beinhalten, empfehlen wir, die Triangulierung zu verwenden, während glatte Oberflächen mittels Punktnormalen verarbeitet werden können. Die Punkt- oder Dreiecksnormalen müssen entweder konsistent ins Innere oder Äußere des Objekts gerichtet sein.

NormalDirectionNormalDirectionNormalDirectionNormalDirectionnormalDirection gibt an, ob die Punkt- oder Dreiecksnormalen nach innen ('inwards'"inwards""inwards""inwards""inwards"), oder außen ('outwards'"outwards""outwards""outwards""outwards") gerichtet sind. Wird nur ein einzelner Wert angegeben, so wird dieser für alle Eingabe-Modelle verwendet. Ansonsten muss die Anzahl Eingabewerte der Anzahl an Eingabe-Modellen entsprechen.

Der umschließende Quader BoundingBoxBoundingBoxBoundingBoxBoundingBoxboundingBox definiert den berücksichtigten Bereich, sowohl die Eingabepunkte als auch die Ausgabepunkte betreffend. Punkte außerhalb des umschließenden Quaders werden verworfen, ebenso auch Dreiecke mit zumindest einem Punkt außerhalb des umschließenden Quaders. Der umschließende Quader BoundingBoxBoundingBoxBoundingBoxBoundingBoxboundingBox wird durch das Tupel [x1,y1,z1,x2,y2,z2] festgelegt, welches die beiden gegenüberliegenden Ecken P1=[x1,y1,z1] und P2=[x2,y2,z2] des Quaders angibt (mit Kanten parallel zu den Koordinatenachsen). Damit der umschließende Quader festgelegt werden kann, muss P1 in der unteren vorderen Ecke und P2 in der oberen hinteren Ecke des Quaders sein, d.h. x1<x2, y1<y2 und z1<z2. Der umschließende Quader wird in der gleichen Einheit gesetzt, die in ObjectModel3DObjectModel3DObjectModel3DObjectModel3DobjectModel3D verwendet wird. Der Operator versucht, eine geschlossene Oberfläche zu kreieren. Falls die Eingabe-Punktwolke das Objekt nur von einer Seite repräsentiert, will man üblicherweise den umschließenden Quader als Begrenzung des unbekannten Teils. Dafür setzt man MinThicknessMinThicknessMinThicknessMinThicknessminThickness z.B. auf einen Wert größer oder gleich der Länge der Diagonale des umschließenden Quaders (welche über get_object_model_3d_paramsget_object_model_3d_paramsGetObjectModel3dParamsGetObjectModel3dParamsGetObjectModel3dParams mit dem Parameter 'diameter_axis_aligned_bounding_box'"diameter_axis_aligned_bounding_box""diameter_axis_aligned_bounding_box""diameter_axis_aligned_bounding_box""diameter_axis_aligned_bounding_box" erhalten werden kann). Wird ein Objekt durch eine Seite des umschließenden Quaders abgeschnitten, hat das Objekt an dieser spezifischen Ebene der Oberfläche keine Punkte, d.h. es ist hohl. Um einen eventuellen unbekannten Teil des Objekts an der richtigen Stelle zu begrenzen, muss die Eingabe-Punktwolke möglicherweise rotiert werden, da die Kanten des umschließenden Quaders immer parallel zu den Koordinatenachsen sind. Eine solche Rotation ist z. B. möglich über die Operatoren affine_trans_object_model_3daffine_trans_object_model_3dAffineTransObjectModel3dAffineTransObjectModel3dAffineTransObjectModel3d oder rigid_trans_object_model_3drigid_trans_object_model_3dRigidTransObjectModel3dRigidTransObjectModel3dRigidTransObjectModel3d.

Die Auflösung ResolutionResolutionResolutionResolutionresolution definiert die Distanz benachbarter Stützstellen in Richtung der Koordinatenachsen bei der Diskretisierung des umschließenden Quaders, BoundingBoxBoundingBoxBoundingBoxBoundingBoxboundingBox. ResolutionResolutionResolutionResolutionresolution wird in der gleichen Einheit gesetzt, die in ObjectModel3DObjectModel3DObjectModel3DObjectModel3DobjectModel3D verwendet wird. Ein zu kleiner Wert, d.h. eine zu hohe Auflösung, wird die Rechenzeit unnötig erhöhen während ein zu großer Wert zu hohem Detailverlust bei der Rekonstruktion führen kann. Wir empfehlen mit einer groben Auflösung zu beginnen. Bei Änderung der Auflösung ResolutionResolutionResolutionResolutionresolution muss SmoothingSmoothingSmoothingSmoothingsmoothing eventuell adaptiert werden. Zudem muss zur Vermeidung von Diskretisierungseffekten ResolutionResolutionResolutionResolutionresolution stets kleiner sein als SurfaceToleranceSurfaceToleranceSurfaceToleranceSurfaceTolerancesurfaceTolerance.

SurfaceToleranceSurfaceToleranceSurfaceToleranceSurfaceTolerancesurfaceTolerance legt fest, wie viel Rauschen der Eingabe-Punktwolke von der Innen- und Außenseite her zur Oberfläche vereint wird. Die Ausnahme ist gegeben durch SurfaceToleranceSurfaceToleranceSurfaceToleranceSurfaceTolerancesurfaceTolerance größer als 'distance_in_front'"distance_in_front""distance_in_front""distance_in_front""distance_in_front", dann bestimmt 'distance_in_front'"distance_in_front""distance_in_front""distance_in_front""distance_in_front" die Dicke der Oberfläche zur Außenseite. SurfaceToleranceSurfaceToleranceSurfaceToleranceSurfaceTolerancesurfaceTolerance wird in der gleichen Einheit gesetzt, die in ObjectModel3DObjectModel3DObjectModel3DObjectModel3DobjectModel3D verwendet wird. SurfaceToleranceSurfaceToleranceSurfaceToleranceSurfaceTolerancesurfaceTolerance gibt die Dicke der Oberfläche an, während MinThicknessMinThicknessMinThicknessMinThicknessminThickness die Dicke des gefüllten Objekts nach innen bestimmt. Daher muss SurfaceToleranceSurfaceToleranceSurfaceToleranceSurfaceTolerancesurfaceTolerance kleiner sein als MinThicknessMinThicknessMinThicknessMinThicknessminThickness. Punkte, die laut NormalDirectionNormalDirectionNormalDirectionNormalDirectionnormalDirection (sowie GenParamNameGenParamNameGenParamNameGenParamNamegenParamName='angle_threshold'"angle_threshold""angle_threshold""angle_threshold""angle_threshold") auf der Innenseite der Objektoberfläche liegen, werden somit als sicher innerhalb eines Objekts betrachtet, wenn ihre Distanz zur initialen Oberfläche größer ist als SurfaceToleranceSurfaceToleranceSurfaceToleranceSurfaceTolerancesurfaceTolerance, aber kleiner als MinThicknessMinThicknessMinThicknessMinThicknessminThickness. Um Diskretisierungseffekte zu vermeiden, muss SurfaceToleranceSurfaceToleranceSurfaceToleranceSurfaceTolerancesurfaceTolerance stets etwas größer als ResolutionResolutionResolutionResolutionresolution sein.

MinThicknessMinThicknessMinThicknessMinThicknessminThickness legt die Dicke des Objekts auf der initialen Oberfläche in Normalenrichtung fest. Sie wird in der gleichen Einheit gesetzt, die in ObjectModel3DObjectModel3DObjectModel3DObjectModel3DobjectModel3D verwendet wird. Punkte, die laut NormalDirectionNormalDirectionNormalDirectionNormalDirectionnormalDirection (sowie GenParamNameGenParamNameGenParamNameGenParamNamegenParamName='angle_threshold'"angle_threshold""angle_threshold""angle_threshold""angle_threshold") auf der Innenseite der Objektoberfläche liegen, werden somit nur als innerhalb des Objekts betrachtet, falls ihre Distanz zur initialen Oberfläche den Wert MinThicknessMinThicknessMinThicknessMinThicknessminThickness nicht überschreitet. Dies kann zu Hohlräumen im Objekt führen. MinThicknessMinThicknessMinThicknessMinThicknessminThickness muss stets größer als SurfaceToleranceSurfaceToleranceSurfaceToleranceSurfaceTolerancesurfaceTolerance sein. Der Operator versucht, eine geschlossene Oberfläche zu erstellen. Für Punktwolken, welche das Objekt von verschiedenen Seiten repräsentieren, wird MinThicknessMinThicknessMinThicknessMinThicknessminThickness am besten als die Dicke des schmalsten Bereichs festgelegt. Sollte die Eingabe-Punktwolke das Objekt nur von einer Seite repräsentieren, will man üblicherweise den umschließenden Quader als Begrenzung des unbekannten Teils. Damit die Ausdehnung des Objekts nicht bereits durch die gesetzte Dicke begrenzt wird, muss MinThicknessMinThicknessMinThicknessMinThicknessminThickness groß genug gesetzt werden. Aufgrund der fehlenden Beobachtung der Objektrückseite wird die Rekonstruktion dieses Teils wahrscheinlich falsch sein. Falls verschiedene Objekte nur von einer Seite betrachtet werden, sollte MinThicknessMinThicknessMinThicknessMinThicknessminThickness kleiner sein, damit die rekonstruierten Objekte schmal genug bleiben, um nicht zu einer Oberfläche zusammengefasst zu werden. Zu kleine Werte können Löcher oder Doppelwände in den vereinigten Punktwolken ergeben. Hingegen können zu große Werte zu einer deformierten Punktwolke oder gar zum Aufblasen der Punktwolke Richtung Oberfläche führen (wird die Oberfläche über den umschließenden Quader hinaus aufgeblasen, so wird sie an der entsprechenden Ebene abgeschnitten und es werden wie oben beschrieben keine Punkte für diese Ebene zurückgegeben).

image/svg+xml SurfaceTolerance MinThickness s o o o o o o c i i i i i s s s s s s s s s s s s s s s s s s s c o c c o i i i i i i i c s o o . . SurfaceTolerance 'distance_in_front' s s image/svg+xml SurfaceTolerance MinThickness s o o o o o o o i i i i i s s s s s s s s s s s s s s s s s s s o o o o o i i i i i i i o o o o . . SurfaceTolerance 'distance_in_front' o o
(1) (2)
Schematische Darstellung der Parameter SurfaceToleranceSurfaceToleranceSurfaceToleranceSurfaceTolerancesurfaceTolerance, MinThicknessMinThicknessMinThicknessMinThicknessminThickness und der Größe 'distance_in_front'"distance_in_front""distance_in_front""distance_in_front""distance_in_front" anhand einer Beispiel-Oberfläche (_.): o sind Punkte außerhalb, s Punkte der Oberfläche, i Punkte sicher im Inneren des Objekts c Punkte die für die Bestimmung der Oberfläche auch miteinbezogen werden. (1): 'distance_in_front'"distance_in_front""distance_in_front""distance_in_front""distance_in_front" kleiner als SurfaceToleranceSurfaceToleranceSurfaceToleranceSurfaceTolerancesurfaceTolerance (2): 'distance_in_front'"distance_in_front""distance_in_front""distance_in_front""distance_in_front" größer als SurfaceToleranceSurfaceToleranceSurfaceToleranceSurfaceTolerancesurfaceTolerance.

SmoothingSmoothingSmoothingSmoothingsmoothing bestimmt, wie eine kleine Gesamtabweichung der Distanzfunktion gegenüber der Datentreue gewichtet wird. Damit kann also die 'Unruhe' der rekonstruierten Oberfläche durch den Glättungsparameter SmoothingSmoothingSmoothingSmoothingsmoothing gesteuert werden. Ein geeigneter Wert für SmoothingSmoothingSmoothingSmoothingsmoothing, um eine passende und visuell ansprechende Oberfläche zu erhalten, muss durch Ausprobieren gefunden werden. Ein zu kleiner Wert führt dazu, dass viele Ausreißer miteinbezogen werden, selbst wenn die Oberfläche dadurch große Sprünge aufweist. Zu große Werte hingegen führen zu Verlust an Wiedergabentreue gegenüber den Eingabe-Punktwolken (wie der Algorithmus die Distanz zu den Eingabe-Punktwolken sieht, hängt stark von SurfaceToleranceSurfaceToleranceSurfaceToleranceSurfaceTolerancesurfaceTolerance und MinThicknessMinThicknessMinThicknessMinThicknessminThickness ab). SmoothingSmoothingSmoothingSmoothingsmoothing muss eventuell adaptiert werden, wenn ResolutionResolutionResolutionResolutionresolution geändert wird.

Mit GenParamNameGenParamNameGenParamNameGenParamNamegenParamName und GenParamValueGenParamValueGenParamValueGenParamValuegenParamValue können die folgenden zusätzlichen Parameternamen und -werte eingestellt werden:

'distance_in_front'"distance_in_front""distance_in_front""distance_in_front""distance_in_front"

Punkte, die gemäß NormalDirectionNormalDirectionNormalDirectionNormalDirectionnormalDirection (sowie GenParamNameGenParamNameGenParamNameGenParamNamegenParamName='angle_threshold'"angle_threshold""angle_threshold""angle_threshold""angle_threshold") auf der Außenseite der Objektoberfläche liegen, werden nur dann als Teil des Objekts betrachtet, wenn ihre Distanz zur initialen Oberfläche nicht größer ist als 'distance_in_front'"distance_in_front""distance_in_front""distance_in_front""distance_in_front". Dies ist das Pendant für die Außenseite zu MinThicknessMinThicknessMinThicknessMinThicknessminThickness der Innenseite, mit der Ausnahme, dass 'distance_in_front'"distance_in_front""distance_in_front""distance_in_front""distance_in_front" auch kleiner als SurfaceToleranceSurfaceToleranceSurfaceToleranceSurfaceTolerancesurfaceTolerance sein darf. Falls 'distance_in_front'"distance_in_front""distance_in_front""distance_in_front""distance_in_front" kleiner ist als SurfaceToleranceSurfaceToleranceSurfaceToleranceSurfaceTolerancesurfaceTolerance, bestimmt dies die Oberflächendicke des Objekts zur Außenseite hin. Dieser Parameter ist nützlich, falls Löcher in der Oberfläche entlang eines Sprunges gefüllt werden sollen (z.B. entlang der Blickrichtung des Sensors). In diesem Fall kann 'distance_in_front'"distance_in_front""distance_in_front""distance_in_front""distance_in_front" auf einen kleinen Wert gesetzt werden, um falsche Initialisierungen zu vermeiden. 'distance_in_front'"distance_in_front""distance_in_front""distance_in_front""distance_in_front" wird in der gleichen Einheit gesetzt, die in ObjectModel3DObjectModel3DObjectModel3DObjectModel3DobjectModel3D verwendet wird. Sie sollte stets etwas größer als ResolutionResolutionResolutionResolutionresolution sein, um Diskretisierungseffekte zu vermeiden. Der Defaultwert für 'distance_in_front'"distance_in_front""distance_in_front""distance_in_front""distance_in_front" ist ein Wert größer als die Raumdiagonale des umschließenden Quaders, wodurch alle Punkte außerhalb des Objekts berücksichtigt werden.

Werteliste: 0.001, 0.1, 1, 10

Defaultwert: größer als die Raumdiagonale des umschließenden Quaders

Restriktion: 'distance_in_front'"distance_in_front""distance_in_front""distance_in_front""distance_in_front" > 0

'angle_threshold'"angle_threshold""angle_threshold""angle_threshold""angle_threshold"

legt den Winkel des Kegels um die Oberflächennormalen fest und wird in [rad] gesetzt. Bei der Bestimmung der Distanzinformation für die Datentreue werden nur jene Punkte berücksichtigt, die innerhalb eines solchen Kegels, mit Spitze auf dem nächsten Oberflächenpunkt, liegen. Wenn Distanzen zu Dreiecken bestimmt werden, kann 'angle_threshold'"angle_threshold""angle_threshold""angle_threshold""angle_threshold" auf 0.0 gesetzt werden, wodurch ausschließlich die Volumen über den Dreiecksflächen (also gerade Prismen) berücksichtigt werden. Werden Punktnormale verwendet und damit Distanzen zu Normalen bestimmt, muss 'angle_threshold'"angle_threshold""angle_threshold""angle_threshold""angle_threshold" auf einen größeren Wert gesetzt werden.

Falls Ausreißer das Resultat stören, kann ein Reduzieren des Wertes 'angle_threshold'"angle_threshold""angle_threshold""angle_threshold""angle_threshold" helfen. Falls Löcher entlang eines Sprunges in der Oberfläche gefüllt werden sollen (z.B. entlang der Blickrichtung des Sensors), kann ein Vergrößern des Wertes für 'angle_threshold'"angle_threshold""angle_threshold""angle_threshold""angle_threshold" helfen.

Werteliste: 'rad(0.0)'"rad(0.0)""rad(0.0)""rad(0.0)""rad(0.0)", 'rad(10.0)'"rad(10.0)""rad(10.0)""rad(10.0)""rad(10.0)", 'rad(30.0)'"rad(30.0)""rad(30.0)""rad(30.0)""rad(30.0)"

Defaultwert: 'rad(10.0)'"rad(10.0)""rad(10.0)""rad(10.0)""rad(10.0)"

Restriktion: 'angle_threshold'"angle_threshold""angle_threshold""angle_threshold""angle_threshold" >= 0

'point_meshing'"point_meshing""point_meshing""point_meshing""point_meshing"

bestimmt, ob die Ausgabepunkte mit dem Algorithmus 'marching tetrahedra' trianguliert werden sollen, Dazu muss 'point_meshing'"point_meshing""point_meshing""point_meshing""point_meshing" auf 'isosurface'"isosurface""isosurface""isosurface""isosurface" gesetzt werden. Wird eine Vermaschung der Isofläche aktiviert, sind auch bei gleicher ResolutionResolutionResolutionResolutionresolution mehr Stützpunkte in ObjectModel3DFusionObjectModel3DFusionObjectModel3DFusionObjectModel3DFusionobjectModel3DFusion.

Wertevorschläge: 'none'"none""none""none""none", 'isosurface'"isosurface""isosurface""isosurface""isosurface"

Defaultwerte: 'isosurface'"isosurface""isosurface""isosurface""isosurface"

Fusions-Algorithmus

Der Algorithmus produziert eine wasserdichte, geschlossene Oberfläche (welche eventuell am umschließenden Quader BoundingBoxBoundingBoxBoundingBoxBoundingBoxboundingBox abgeschnitten ist). Ziel ist es, eine möglichst glatte und trotzdem formtreue Oberfläche zu erhalten. Dazu wird der umschließende Quader gesampelt und jedem Sample-Punkt ein Distanzwert zu einer sogenannten Isofläche (bestehend aus Punkten mit Distanzwert 0) zugewiesen. Die endgültigen Distanzwerte (und somit die Isofläche) erhält man durch Minimierung einer Fehlerfunktion, basierend sowohl auf der Datentreue zur Eingabe-Punktwolke als auch der totalen Variation ('Sprunghaftigkeit') der Distanzfunktion. Dadurch erreicht man eine Fusion der Eingabe-Punktwolken (siehe das Paper unter Referenzen).

Die Berechnung der Isofläche kann durch die Parameter des Operators beeinflusst werden. Die Auflösung, d.h. die Distanz zwischen den Stützstellen des umschließenden Quaders (in Richtung der Koordinatenachsen), kann durch den Parameter ResolutionResolutionResolutionResolutionresolution bestimmt werden.

Datentreue zu den Eingabe-Punktwolken wird erfasst als die vorzeichenbehafteten Distanzen der Abtastpunkte, d.h. Stützstellen des umschließende Quaders, zu ihren nächsten Nachbarn (Punkte oder Dreiecke) der Eingabe-Punktwolke. Ob ein Abtastpunkt als innerhalb oder außerhalb des Objektes liegend betrachtet wird (Vorzeichen der Distanz), wird bestimmt durch die Normale des nächsten Nachbarn auf der initialen Oberfläche und der gesetzten Richtung NormalDirectionNormalDirectionNormalDirectionNormalDirectionnormalDirection. Um zu bestimmen, ob ein Abtastpunkt in Bezug auf die Eingabe-Punktwolke sicher innerhalb oder außerhalb eines Objektes liegt, wird die Distanz zum nächsten Nachbarn auf der initialen Oberfläche bestimmt. Ein Abtastpunkt der Innenseite wird als sicher im Objekt liegend betrachtet, wenn die Distanz größer als SurfaceToleranceSurfaceToleranceSurfaceToleranceSurfaceTolerancesurfaceTolerance, aber kleiner als MinThicknessMinThicknessMinThicknessMinThicknessminThickness ist, während ein Abtastpunkt der Außenseite als außerhalb gilt, wenn die Distanz größer 'distance_in_front'"distance_in_front""distance_in_front""distance_in_front""distance_in_front" ist.

Datentreue zu den Eingabe-Punktwolken wird nur berücksichtigt für Abtastpunkte, die maximal MinThicknessMinThicknessMinThicknessMinThicknessminThickness innerhalb oder GenParamNameGenParamNameGenParamNameGenParamNamegenParamName 'distance_in_front'"distance_in_front""distance_in_front""distance_in_front""distance_in_front" außerhalb der initialen Oberfläche liegen.

Des Weiteren wird die Datentreue für einen gegebenen Abtastpunkt nicht gepflegt, falls er nicht innerhalb eines Kegels mit Winkel GenParamNameGenParamNameGenParamNameGenParamNamegenParamName 'angle_threshold'"angle_threshold""angle_threshold""angle_threshold""angle_threshold" liegt. Also dann nicht, wenn die Verbindungslinie des Abtastpunktes zu seinem nächsten Nachbarn auf der initialen Oberfläche und die Oberflächennormale des nächsten Nachbarn einen Winkel größer als GenParamNameGenParamNameGenParamNameGenParamNamegenParamName 'angle_threshold'"angle_threshold""angle_threshold""angle_threshold""angle_threshold" bilden. Während die Distanz zu nächsten Nachbarsdreiecken oft überzeugendere Resultate liefert, können die Distanzen zu den nächsten Punkten viel schneller berechnet werden.

Die anschließende Optimierung der Distanzwerte ist die selbe wie in reconstruct_surface_stereoreconstruct_surface_stereoReconstructSurfaceStereoReconstructSurfaceStereoReconstructSurfaceStereo mit Method='surface_fusion'"surface_fusion""surface_fusion""surface_fusion""surface_fusion".

Der Parameter SmoothingSmoothingSmoothingSmoothingsmoothing reguliert die 'Sprunghaftigkeit' der Distanzfunktion durch Gewichten der beiden Terme in der Fehlerfunktion: Datentreue zur Eingabe-Punktwolke einerseits, Gesamtabweichung der Distanzfunktion andererseits. Der geeignete Wert für SmoothingSmoothingSmoothingSmoothingsmoothing, um eine passende und visuell ansprechende Oberfläche zu erhalten, muss durch Ausprobieren gefunden werden.

Die 3D Punkte des in ObjectModel3DFusionObjectModel3DFusionObjectModel3DFusionObjectModel3DFusionobjectModel3DFusion zurückgegebenen Objektmodells stammen aus der Isofläche, auf der die Distanzfunktion Null ist. Die Normalen werden aus dem Gradienten der Distanzfunktion berechnet. Die dadurch erhaltene Punktwolke kann auch vermascht werden mittels Algorithmus 'marching tetrahedra' durch Setzen des Parameters GenParamNameGenParamNameGenParamNameGenParamNamegenParamName 'point_meshing'"point_meshing""point_meshing""point_meshing""point_meshing" auf GenParamValueGenParamValueGenParamValueGenParamValuegenParamValue 'isosurface'"isosurface""isosurface""isosurface""isosurface".

Troubleshooting

Es wird empfohlen, sich an den oben stehenden Ablauf zu halten. Wenn die Rekonstruktionsergebnisse nicht zufriedenstellend sind, können die folgenden Verbesserungsmaßnahmen versucht werden:

Qualität der Eingabe-Punktwolken

Die Eingabe-Punktwolken sollten die gesamte Objektoberfläche repräsentieren. Falls Punktnormalen benutzt werden, sollten die Punkte auf der ganzen Oberfläche dicht liegen und nicht nur entlang der Objektkanten. Insbesondere mit CAD-Daten sollte die Triangulierung verwendet werden.

Verwendete Attribute

Das Verwenden von Dreiecken statt Punktnormalen führt typischerweise zu besseren Ergebnissen. Sollten beide Attribute vorhanden sein, werden, aufgrund der Geschwindigkeitsvorteile, als Standardeinstellung Punktnormalen verwendet. Bei Bevorzugung von Dreiecken verwenden Sie bitte copy_object_model_3dcopy_object_model_3dCopyObjectModel3dCopyObjectModel3dCopyObjectModel3d, damit nur Informationen zu Punkten und Dreiecken vorhanden sind.

Ausreißer

Falls Ausreißer des Eingabe-Modells die ausgegebene Oberfläche selbst für große Werte von SmoothingSmoothingSmoothingSmoothingsmoothing stören, kann man versuchen, GenParamNameGenParamNameGenParamNameGenParamNamegenParamName 'angle_threshold'"angle_threshold""angle_threshold""angle_threshold""angle_threshold" zu reduzieren. Falls gewünscht, können Ausreißer des Eingabe-Modells auch entfernt werden, z.B. mittels connection_object_model_3dconnection_object_model_3dConnectionObjectModel3dConnectionObjectModel3dConnectionObjectModel3d. In kleinerem Ausmaß kann auch das Modifizieren von GenParamNameGenParamNameGenParamNameGenParamNamegenParamName 'distance_in_front'"distance_in_front""distance_in_front""distance_in_front""distance_in_front" helfen, gewisse Ausreißer zu minimieren.

Löcher füllen

Falls Löcher selbst für große Werte von SmoothingSmoothingSmoothingSmoothingsmoothing nicht gefüllt werden (z.B. ein Sprung der Oberfläche in Blickrichtung des Sensors), kann man versuchen, GenParamNameGenParamNameGenParamNameGenParamNamegenParamName 'distance_in_front'"distance_in_front""distance_in_front""distance_in_front""distance_in_front" zu reduzieren. Vergrößern von GenParamNameGenParamNameGenParamNameGenParamNamegenParamName 'angle_threshold'"angle_threshold""angle_threshold""angle_threshold""angle_threshold" kann dem Algorithmus helfen, die Löcher zu schließen. Beachten Sie, dass triangulate_object_model_3dtriangulate_object_model_3dTriangulateObjectModel3dTriangulateObjectModel3dTriangulateObjectModel3d beim Triangulieren Löcher von Sensordaten, welche eine 2D Zuordnung enthalten, füllen kann.

Leerer Rückgabewert

Ist die Rückgabe leer, kann man versuchen, SmoothingSmoothingSmoothingSmoothingsmoothing zu reduzieren. Sollte die Rückgabe selbst für sehr kleine Werte von SmoothingSmoothingSmoothingSmoothingsmoothing leer bleiben, empfehlen wir zu überprüfen, ob ob MinThicknessMinThicknessMinThicknessMinThicknessminThickness zu groß ist und ob die NormalDirectionNormalDirectionNormalDirectionNormalDirectionnormalDirection richtig gesetzt ist.

Rechenzeit

Um die Rechenzeit zu verkürzen, empfehlen wir folgende Punkte zu beachten:

Ausdehnung des umschließenden Quaders

Der umschließende Quader sollte möglichst eng um die zu fusionierenden Punktwolken liegen. Ansonsten wird die Rechenzeit erheblich erhöht, ohne irgendeinen Vorteil zu generieren.

Auflösung

Ein höherer Wert für die Auflösung ResolutionResolutionResolutionResolutionresolution beschleunigt die Fusion merklich.

Verwendete Attribute

Das Verwenden von Punktnormalen anstelle von Dreiecken beschleunigt die Ausführung. Sollten beide Attribute vorhanden sein, werden als Standardeinstellung Punktnormalen verwendet.

Dichte der Eingabe-Punktewolken

Die Eingabe-Punktwolken können ausgedünnt werden ,entweder mittels sample_object_model_3dsample_object_model_3dSampleObjectModel3dSampleObjectModel3dSampleObjectModel3d (falls Punktnormalen verwendet werden) oder mittels simplify_object_model_3dsimplify_object_model_3dSimplifyObjectModel3dSimplifyObjectModel3dSimplifyObjectModel3d mit 'true'"true""true""true""true" für den Parameter GenParamNameGenParamNameGenParamNameGenParamNamegenParamName 'avoid_triangle_flips'"avoid_triangle_flips""avoid_triangle_flips""avoid_triangle_flips""avoid_triangle_flips" (bei Verwendung von Dreiecken).

Oberflächendistanz

Unnötig große Werte für MinThicknessMinThicknessMinThicknessMinThicknessminThickness und GenParamNameGenParamNameGenParamNameGenParamNamegenParamName 'distance_in_front'"distance_in_front""distance_in_front""distance_in_front""distance_in_front" können die Vorbereitung und die Distanzberechnung verlangsamen.

Ausführungsinformationen

Parameter

ObjectModel3DObjectModel3DObjectModel3DObjectModel3DobjectModel3D (input_control)  object_model_3d(-array) HObjectModel3D, HTupleHTupleHtuple (handle) (IntPtr) (HHandle) (handle)

Handle eines 3D-Objektmodells.

BoundingBoxBoundingBoxBoundingBoxBoundingBoxboundingBox (input_control)  number-array HTupleHTupleHtuple (real / integer) (double / int / long) (double / Hlong) (double / Hlong)

Zwei gegenüberliegende Ecken des umschließenden Quaders.

ResolutionResolutionResolutionResolutionresolution (input_control)  number HTupleHTupleHtuple (real / integer) (double / int / long) (double / Hlong) (double / Hlong)

Verwendete Auflösung innerhalb des umschließenden Quaders.

Defaultwert: 1.0

Wertevorschläge: 1.0, 1.1, 1.5, 10.0, 100.0

SurfaceToleranceSurfaceToleranceSurfaceToleranceSurfaceTolerancesurfaceTolerance (input_control)  number HTupleHTupleHtuple (real / integer) (double / int / long) (double / Hlong) (double / Hlong)

Distanz des erwarteten Rauschens zur Oberfläche.

Defaultwert: 1.0

Wertevorschläge: 1.0, 1.1, 1.5, 10.0, 100.0

MinThicknessMinThicknessMinThicknessMinThicknessminThickness (input_control)  number HTupleHTupleHtuple (real / integer) (double / int / long) (double / Hlong) (double / Hlong)

Minimale Dicke des Objekts in Richtung Normale zur Oberfläche.

Defaultwert: 1.0

Wertevorschläge: 1.0, 1.1, 1.5, 10.0, 100.0

SmoothingSmoothingSmoothingSmoothingsmoothing (input_control)  number HTupleHTupleHtuple (real / integer) (double / int / long) (double / Hlong) (double / Hlong)

Gewichtungsfaktor zur Datentreue.

Defaultwert: 1.0

Wertevorschläge: 1.0, 1.1, 1.5, 10.0, 100.0

NormalDirectionNormalDirectionNormalDirectionNormalDirectionnormalDirection (input_control)  string(-array) HTupleHTupleHtuple (string) (string) (HString) (char*)

Richtung der Normalen im Eingabe-Modell.

Defaultwert: 'inwards' "inwards" "inwards" "inwards" "inwards"

Werteliste: 'inwards'"inwards""inwards""inwards""inwards", 'outwards'"outwards""outwards""outwards""outwards"

GenParamNameGenParamNameGenParamNameGenParamNamegenParamName (input_control)  attribute.name-array HTupleHTupleHtuple (string) (string) (HString) (char*)

Name des generischen Parameters.

Defaultwert: []

Werteliste: 'angle_threshold'"angle_threshold""angle_threshold""angle_threshold""angle_threshold", 'distance_in_front'"distance_in_front""distance_in_front""distance_in_front""distance_in_front", 'point_meshing'"point_meshing""point_meshing""point_meshing""point_meshing"

GenParamValueGenParamValueGenParamValueGenParamValuegenParamValue (input_control)  attribute.value-array HTupleHTupleHtuple (string / real / integer) (string / double / int / long) (HString / double / Hlong) (char* / double / Hlong)

Wert des generischen Parameters.

Defaultwert: []

Wertevorschläge: 'isosurface'"isosurface""isosurface""isosurface""isosurface", 'none'"none""none""none""none", 0.0, 0.1, 0.175, 0.524

ObjectModel3DFusionObjectModel3DFusionObjectModel3DFusionObjectModel3DFusionobjectModel3DFusion (output_control)  object_model_3d HObjectModel3D, HTupleHTupleHtuple (handle) (IntPtr) (HHandle) (handle)

Handle des fusionierten 3D-Objektmodelles.

Ergebnis

fuse_object_model_3dfuse_object_model_3dFuseObjectModel3dFuseObjectModel3dFuseObjectModel3d liefert den Wert 2 (H_MSG_TRUE) wenn alle Parameter korrekt sind. Andernfalls wird eine Fehlerbehandlung durchgeführt.

Vorgänger

read_object_model_3dread_object_model_3dReadObjectModel3dReadObjectModel3dReadObjectModel3d, register_object_model_3d_pairregister_object_model_3d_pairRegisterObjectModel3dPairRegisterObjectModel3dPairRegisterObjectModel3dPair, register_object_model_3d_globalregister_object_model_3d_globalRegisterObjectModel3dGlobalRegisterObjectModel3dGlobalRegisterObjectModel3dGlobal, surface_normals_object_model_3dsurface_normals_object_model_3dSurfaceNormalsObjectModel3dSurfaceNormalsObjectModel3dSurfaceNormalsObjectModel3d, triangulate_object_model_3dtriangulate_object_model_3dTriangulateObjectModel3dTriangulateObjectModel3dTriangulateObjectModel3d, simplify_object_model_3dsimplify_object_model_3dSimplifyObjectModel3dSimplifyObjectModel3dSimplifyObjectModel3d, get_object_model_3d_paramsget_object_model_3d_paramsGetObjectModel3dParamsGetObjectModel3dParamsGetObjectModel3dParams

Nachfolger

write_object_model_3dwrite_object_model_3dWriteObjectModel3dWriteObjectModel3dWriteObjectModel3d, create_surface_modelcreate_surface_modelCreateSurfaceModelCreateSurfaceModelCreateSurfaceModel

Siehe auch

reconstruct_surface_stereoreconstruct_surface_stereoReconstructSurfaceStereoReconstructSurfaceStereoReconstructSurfaceStereo

Literatur

C. Zach, T. Pock, and H. Bischof: „A globally optimal algorithm for robust TV-L1 range image integration.“ Proceedings of IEEE International Conference on Computer Vision (ICCV 2007).

Modul

3D Metrology