trimesh.registration module¶

registration.py¶

Functions for registering (aligning) point clouds with meshes.

trimesh.registration.icp(a, b, initial=None, threshold=1e-05, max_iterations=20, **kwargs)

Apply the iterative closest point algorithm to align a point cloud with another point cloud or mesh. Will only produce reasonable results if the initial transformation is roughly correct. Initial transformation can be found by applying Procrustes’ analysis to a suitable set of landmark points (often picked manually).

Parameters:
• a ((n,3) float) – List of points in space.

• b ((m,3) float or Trimesh) – List of points in space or mesh.

• initial ((4,4) float) – Initial transformation.

• threshold (float) – Stop when change in cost is less than threshold

• max_iterations (int) – Maximum number of iterations

• kwargs (dict) – Args to pass to procrustes

Returns:

• matrix ((4,4) float) – The transformation matrix sending a to b

• transformed ((n,3) float) – The image of a under the transformation

• cost (float) – The cost of the transformation

trimesh.registration.mesh_other(mesh, other, samples: int | integer | unsignedinteger = 500, scale: bool = False, icp_first: int | integer | unsignedinteger = 10, icp_final: int | integer | unsignedinteger = 50, **kwargs)

Align a mesh with another mesh or a PointCloud using the principal axes of inertia as a starting point which is refined by iterative closest point.

Parameters:
• mesh (trimesh.Trimesh object) – Mesh to align with other

• other (trimesh.Trimesh or (n, 3) float) – Mesh or points in space

• samples (int) – Number of samples from mesh surface to align

• scale (bool) – Allow scaling in transform

• icp_first (int) – How many ICP iterations for the 9 possible combinations of sign flippage

• icp_final (int) – How many ICP iterations for the closest candidate from the wider search

• kwargs (dict) – Passed through to icp, which passes through to procrustes

Returns:

• mesh_to_other ((4, 4) float) – Transform to align mesh to the other object

• cost (float) – Average squared distance per point

trimesh.registration.nricp_amberg(source_mesh, target_geometry, source_landmarks=None, target_positions=None, steps=None, eps=0.0001, gamma=1, distance_threshold=0.1, return_records=False, use_faces=True, use_vertex_normals=True, neighbors_count=8)

Non Rigid Iterative Closest Points

Implementation of “Amberg et al. 2007: Optimal Step Nonrigid ICP Algorithms for Surface Registration.” Allows to register non-rigidly a mesh on another or on a point cloud. The core algorithm is explained at the end of page 3 of the paper.

Comparison between nricp_amberg and nricp_sumner: * nricp_amberg fits to the target mesh in less steps * nricp_amberg can generate sharp edges

• only vertices and their neighbors are considered

• nricp_sumner tend to preserve more the original shape

• nricp_sumner parameters are easier to tune

• nricp_sumner solves for triangle positions whereas nricp_amberg solves for vertex transforms

• nricp_sumner is less optimized when wn > 0

Parameters:
• source_mesh (Trimesh) – Source mesh containing both vertices and faces.

• target_geometry (Trimesh or PointCloud or (n, 3) float) – Target geometry. It can contain no faces or be a PointCloud.

• source_landmarks ((n,) int or ((n,) int, (n, 3) float)) – n landmarks on the the source mesh. Represented as vertex indices (n,) int. It can also be represented as a tuple of triangle indices and barycentric coordinates ((n,) int, (n, 3) float,).

• target_positions ((n, 3) float) – Target positions assigned to source landmarks

• steps (Core parameters of the algorithm) – Iterable of iterables (ws, wl, wn, max_iter,). ws is smoothness term, wl weights landmark importance, wn normal importance and max_iter is the maximum number of iterations per step.

• eps (float) – If the error decrease if inferior to this value, the current step ends.

• gamma (float) – Weight the translation part against the rotational/skew part. Recommended value : 1.

• distance_threshold (float) – Distance threshold to account for a vertex match or not.

• return_records (bool) – If True, also returns all the intermediate results. It can help debugging and tune the parameters to match a specific case.

• use_faces (bool) – If True and if target geometry has faces, use proximity.closest_point to find matching points. Else use scipy’s cKDTree object.

• use_vertex_normals (bool) – If True and if target geometry has faces, interpolate the normals of the target geometry matching points. Else use face normals or estimated normals if target geometry has no faces.

• neighbors_count (int) – number of neighbors used for normal estimation. Only used if target geometry has no faces or if use_faces is False.

Returns:

result – The vertices positions of source_mesh such that it is registered non-rigidly onto the target geometry. If return_records is True, it returns the list of the vertex positions at each iteration.

Return type:

(n, 3) float or List[(n, 3) float]

trimesh.registration.nricp_sumner(source_mesh, target_geometry, source_landmarks=None, target_positions=None, steps=None, distance_threshold=0.1, return_records=False, use_faces=True, use_vertex_normals=True, neighbors_count=8, face_pairs_type='vertex')

Non Rigid Iterative Closest Points

Implementation of the correspondence computation part of “Sumner and Popovic 2004: Deformation Transfer for Triangle Meshes” Allows to register non-rigidly a mesh on another geometry.

Comparison between nricp_amberg and nricp_sumner: * nricp_amberg fits to the target mesh in less steps * nricp_amberg can generate sharp edges (only vertices and their

neighbors are considered)

• nricp_sumner tend to preserve more the original shape

• nricp_sumner parameters are easier to tune

• nricp_sumner solves for triangle positions whereas nricp_amberg solves for

vertex transforms

• nricp_sumner is less optimized when wn > 0

Parameters:
• source_mesh (Trimesh) – Source mesh containing both vertices and faces.

• target_geometry (Trimesh or PointCloud or (n, 3) float) – Target geometry. It can contain no faces or be a PointCloud.

• source_landmarks ((n,) int or ((n,) int, (n, 3) float)) – n landmarks on the the source mesh. Represented as vertex indices (n,) int. It can also be represented as a tuple of triangle indices and barycentric coordinates ((n,) int, (n, 3) float,).

• target_positions ((n, 3) float) – Target positions assigned to source landmarks

• steps (Core parameters of the algorithm) – Iterable of iterables (wc, wi, ws, wl, wn). wc is the correspondence term (strength of fitting), wi is the identity term (recommended value : 0.001), ws is smoothness term, wl weights the landmark importance and wn the normal importance.

• distance_threshold (float) – Distance threshold to account for a vertex match or not.

• return_records (bool) – If True, also returns all the intermediate results. It can help debugging and tune the parameters to match a specific case.

• use_faces (bool) – If True and if target geometry has faces, use proximity.closest_point to find matching points. Else use scipy’s cKDTree object.

• use_vertex_normals (bool) – If True and if target geometry has faces, interpolate the normals of the target geometry matching points. Else use face normals or estimated normals if target geometry has no faces.

• neighbors_count (int) – number of neighbors used for normal estimation. Only used if target geometry has no faces or if use_faces is False.

• face_pairs_type (str 'vertex' or 'edge') – Method to determine face pairs used in the smoothness cost. ‘vertex’ yields smoother results.

Returns:

result – The vertices positions of source_mesh such that it is registered non-rigidly onto the target geometry. If return_records is True, it returns the list of the vertex positions at each iteration.

Return type:

(n, 3) float or List[(n, 3) float]

trimesh.registration.procrustes(a: Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes], b: Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes], weights: Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes] | None = None, reflection: bool = True, translation: bool = True, scale: bool = True, return_cost: bool = True)

Perform Procrustes’ analysis to quickly align two corresponding point clouds subject to constraints. This is much cheaper than any other registration method but only applies if the two inputs correspond in order.

Finds the transformation T mapping a to b which minimizes the square sum distances between Ta and b, also called the cost.

Optionally specify different weights for the points in a to minimize the weighted square sum distances between Ta and b, which can improve transformation robustness on noisy data if the points’ probability distribution is known.

Parameters:
• a ((n,3) float) – List of points in space

• b ((n,3) float) – List of points in space

• weights ((n,) float) – List of floats representing how much weight is assigned to each point of a

• reflection (bool) – If the transformation is allowed reflections

• translation (bool) – If the transformation is allowed translation and rotation.

• scale (bool) – If the transformation is allowed scaling

• return_cost (bool) – Whether to return the cost and transformed a as well

Returns:

• matrix ((4,4) float) – The transformation matrix sending a to b

• transformed ((n,3) float) – The image of a under the transformation

• cost (float) – The cost of the transformation