コード例 #1
0
ファイル: icp_numpy.py プロジェクト: irfanirw/compas
def icp_numpy(source, target, tol=1e-3):
    """Align two point clouds using the Iterative Closest Point (ICP) method.

    Parameters
    ----------
    source : list of point
        The source data.
    target : list of point
        The target data.
    tol : float, optional
        Tolerance for finding matches.
        Default is ``1e-3``.

    Returns
    -------

        The transformed points

    Notes
    -----
    First we align the source with the target cloud using the frames resulting
    from a PCA of each of the clouds, simply by calculating a frame-to-frame transformation.

    This initial alignment is used to establish an initial correspondence between
    the points of the two clouds.

    Then we iteratively improve the alignment by computing successive "best-fit"
    transformations using SVD of the cross-covariance matrix of the two data sets.
    During this iterative process, we continuously update the correspondence
    between the point clouds by finding the closest point in the target to each
    of the source points.

    The algorithm terminates when the alignment error is below a specified tolerance.

    Examples
    --------
    >>>

    """
    A = asarray(source)
    B = asarray(target)

    origin, axes, _ = pca_numpy(A)
    A_frame = Frame(origin, axes[0], axes[1])

    origin, axes, _ = pca_numpy(B)
    B_frame = Frame(origin, axes[0], axes[1])

    X = Transformation.from_frame_to_frame(A_frame, B_frame)
    A = transform_points_numpy(A, X)

    for i in range(20):
        D = cdist(A, B, 'euclidean')
        closest = argmin(D, axis=1)
        if norm(normrow(A - B[closest])) < tol:
            break
        X = bestfit_transform(A, B[closest])
        A = transform_points_numpy(A, X)

    return A, X
コード例 #2
0
ファイル: bbox_numpy.py プロジェクト: yishizu/compas
def oabb_numpy(points):
    origin, (xaxis, yaxis, zaxis), values = pca_numpy(points)
    frame = Frame(origin, xaxis, yaxis)
    world = Frame.worldXY()
    X = Transformation.from_frame_to_frame(frame, world)
    points = transform_points_numpy(points, X)
    bbox = bounding_box(points)
    bbox = transform_points_numpy(bbox, X.inverse())
    return bbox
コード例 #3
0
def mesh_transform_numpy(mesh, transformation):
    """Transform a mesh.

    Parameters
    ----------
    mesh : compas.datastructures.Mesh
        The mesh.
    transformation : compas.geometry.Transformation
        The transformation.

    Notes
    -----
    The mesh is modified in-place.

    Examples
    --------
    >>> mesh = Mesh.from_obj(compas.get('cube.obj'))
    >>> T = matrix_from_axis_and_angle([0, 0, 1], pi / 4)
    >>> tmesh = mesh.copy()
    >>> mesh_transform(tmesh, T)

    """
    vertices = [mesh.vertex_coordinates(key) for key in mesh.vertices()]
    xyz = transform_points_numpy(vertices, transformation)
    for index, (_, attr) in enumerate(mesh.vertices(True)):
        attr['x'] = xyz[index][0]
        attr['y'] = xyz[index][1]
        attr['z'] = xyz[index][2]
コード例 #4
0
def mesh_transform_numpy(mesh, transformation):
    """Transform a mesh.

    Parameters
    ----------
    mesh : compas.datastructures.Mesh
        The mesh.
    transformation : compas.geometry.Transformation
        The transformation.

    Notes
    -----
    The mesh is modified in-place.

    Examples
    --------
    >>> mesh = Mesh.from_obj(compas.get('cube.obj'))
    >>> T = matrix_from_axis_and_angle([0, 0, 1], pi / 4)
    >>> tmesh = mesh.copy()
    >>> mesh_transform(tmesh, T)

    """
    vertices = list(mesh.vertices())
    xyz = [mesh.vertex_coordinates(vertex) for vertex in vertices]
    xyz[:] = transform_points_numpy(xyz, transformation)
    for index, vertex in enumerate(vertices):
        mesh.vertex_attributes(vertex, 'xyz', xyz[index])
コード例 #5
0
def mesh_transform_numpy(mesh, transformation):
    """Transform a mesh.

    Parameters
    ----------
    mesh : :class:`compas.datastructures.Mesh`
        The mesh.
    transformation : :class:`compas.geometry.Transformation`
        The transformation.

    Returns
    -------
    None
        The mesh is modified in-place.

    Examples
    --------
    >>> from compas.datastructures import Mesh
    >>> from compas.geometry import matrix_from_axis_and_angle
    >>> mesh = Mesh.from_polyhedron(6)
    >>> T = matrix_from_axis_and_angle([0, 0, 1], math.pi / 4)
    >>> tmesh = mesh.copy()
    >>> mesh_transform_numpy(tmesh, T)

    """
    vertices = list(mesh.vertices())
    xyz = [mesh.vertex_coordinates(vertex) for vertex in vertices]
    xyz[:] = transform_points_numpy(xyz, transformation)
    for index, vertex in enumerate(vertices):
        mesh.vertex_attributes(vertex, 'xyz', xyz[index])
コード例 #6
0
def icp_numpy(d1, d2, tol=1e-3):
    """Align two point clouds using the Iterative Closest Point (ICP) method.

    Parameters
    ----------
    d1 : list of point
        Point cloud 1.
    d2 : list of point
        Point cloud 2.
    tol : float, optional
        Tolerance for finding matches.
        Default is ``1e-3``.

    Returns
    -------

    Notes
    -----

    Examples
    --------

    References
    ----------

    """
    d1 = asarray(d1)
    d2 = asarray(d2)

    point, axes, spread = pca_numpy(d1)
    frame1 = Frame(point, axes[0], axes[1])

    point, axes, spread = pca_numpy(d2)
    frame2 = Frame(point, axes[0], axes[1])

    T = Transformation.from_frame_to_frame(frame1, frame2)
    transform_points_numpy(d1, T)

    y = cdist(d1, d2, 'eucledian')
    closest = argmin(y, axes=1)
コード例 #7
0
def oabb_numpy(points):
    """Oriented bounding box of a set of points.

    Parameters
    ----------
    points : array_like[point]
        XYZ coordinates of the points.

    Returns
    -------
    list[[float, float, float]]
        XYZ coordinates of 8 points defining a box.

    """
    origin, (xaxis, yaxis, zaxis), values = pca_numpy(points)
    frame = Frame(origin, xaxis, yaxis)
    world = Frame.worldXY()
    X = Transformation.from_frame_to_frame(frame, world)
    points = transform_points_numpy(points, X)
    bbox = bounding_box(points)
    bbox = transform_points_numpy(bbox, X.inverse())
    return bbox
コード例 #8
0
    from compas_plotters import Axes3D
    from compas_plotters import Cloud3D
    from compas_plotters import Bounds
    from compas_plotters import create_axes_3d

    data = random.rand(300, 3)
    data[:, 0] *= 10.0
    data[:, 1] *= 1.0
    data[:, 2] *= 4.0

    a = 3.14159 * 30.0 / 180
    Ry = matrix_from_axis_and_angle([0, 1.0, 0.0], a, rtype='array')

    a = -3.14159 * 45.0 / 180
    Rz = matrix_from_axis_and_angle([0, 0, 1.0], a, rtype='array')

    R = Rz.dot(Ry)

    data = transform_points_numpy(data, R)

    average, vectors, values = pca_numpy(data)

    axes = create_axes_3d()

    Bounds(data).plot(axes)
    Cloud3D(data).plot(axes)
    Axes3D(average, vectors).plot(axes)

    plt.show()
コード例 #9
0
 def transform(self, X):
     transform_points_numpy(self._data, X)
コード例 #10
0
import time
import compas
from compas.datastructures import Mesh
from compas.geometry import Rotation
from compas.geometry import transform_points
from compas.geometry import transform_points_numpy

# load mesh
mesh = Mesh.from_ply(compas.get('bunny.ply'))
v, f = mesh.to_vertices_and_faces()
print("The mesh has {} vertices.".format(len(v)))

# create Transformation
T = Rotation.from_axis_and_angle([-0.248, -0.786, -0.566],
                                 2.78,
                                 point=[1.0, 0.0, 0.0])

# transform points with transform_points
t0 = time.time()
transform_points(v, T)
print("transfrom_points takes {:.4f} seconds.".format(time.time() - t0))

# transform points with transform_points_numpy
t0 = time.time()
transform_points_numpy(v, T)
print("transfrom_points_numpy takes {:.4f} seconds.".format(time.time() - t0))
コード例 #11
0
    from compas.geometry import transform_points_numpy
    from compas.geometry import allclose

    points = numpy.random.rand(10000, 3)
    bottom = numpy.array([[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0],
                          [1.0, 1.0, 0.0]])
    top = numpy.array([[0.0, 0.0, 1.0], [1.0, 0.0, 1.0], [0.0, 1.0, 1.0],
                       [1.0, 1.0, 1.0]])
    points = numpy.concatenate((points, bottom, top))
    points[:, 0] *= 10
    points[:, 2] *= 3

    bbox = bounding_box(points)
    a = length_vector(subtract_vectors(bbox[1], bbox[0]))
    b = length_vector(subtract_vectors(bbox[3], bbox[0]))
    c = length_vector(subtract_vectors(bbox[4], bbox[0]))
    v1 = a * b * c

    R = Rotation.from_axis_and_angle([1.0, 1.0, 0.0], 0.5 * 3.14159)
    points = transform_points_numpy(points, R.matrix)

    bbox = oriented_bounding_box_numpy(points)

    a = length_vector(subtract_vectors(bbox[1], bbox[0]))
    b = length_vector(subtract_vectors(bbox[3], bbox[0]))
    c = length_vector(subtract_vectors(bbox[4], bbox[0]))
    v2 = a * b * c

    print(v1, v2)
    print(allclose([v1], [v2]))
コード例 #12
0
ファイル: trimesh.py プロジェクト: tetov/compas_cgal
 def transform(self, T):
     """Transform the triangle mesh."""
     self.vertices[:] = transform_points_numpy(self.vertices, T)