点云拼接主要是把不同的点云拼接到一起。通常,为了获得一个完整物体的三维点云,我们可能会在不同的视点进行数据采集,然后把采集的点云数据拼接到一起。由于视点的不同,所采集到的多个点云的坐标系也会不一致。为了解决坐标系不一致的问题,最可能用到点云配准技术,或者提前知道视点间的坐标关系。
对于上述已经配准好的数据,这里就可以直接将配准好的数据与目标点云进行拼接,实现视角的补充。这里使用最普通的Numpy将两个数据矩阵进行拼接,既两个点云叠加。这会导致点云数据量显著增加。因此可以用一些下采样的方法,或者将距离相近的点合并为一个点。(点云下采样的方法可以有效的减少点云数据,又不至于影响整体效果)
import open3d
import numpy as np
import mayavi.mlab as mlab
def open3d_registration():
ply_path = r"E:\xxxx\xxx\3D_tools_data\reconstruction\xxxx.ply"
ply = open3d.io.read_triangle_mesh(ply_path)
point_s1 = np.array(ply.vertices)
ply_path = r"E:\xxxxx\3D_tools_data\reconstruction\xxxxxx3.ply"
ply = open3d.io.read_triangle_mesh(ply_path)
point_s2 = np.array(ply.vertices)
print(point_s1.shape, point_s2.shape)
source = open3d.geometry.PointCloud()
source.points = open3d.utility.Vector3dVector(point_s1)
target = open3d.geometry.PointCloud()
target.points = open3d.utility.Vector3dVector(point_s2)
icp = open3d.pipelines.registration.registration_icp(
source=source,
target=target,
max_correspondence_distance=0.2, # 距离阈值
estimation_method=open3d.pipelines.registration.TransformationEstimationPointToPoint()
)
print(icp)
source.transform(icp.transformation)
points = np.array(source.points)
# 配准可视化
# x = points[:, 0]
# y = points[:, 1]
# z = points[:, 2]
# fig = mlab.figure(bgcolor=(0, 0, 0), size=(640, 640))
# mlab.points3d(x, y, z, x, mode="point", color=(0, 0, 1), figure=fig) # 蓝色
#
# x = point_s1[:, 0]
# y = point_s1[:, 1]
# z = point_s1[:, 2]
# mlab.points3d(x, y, z, x, mode="point", color=(0, 1, 0), figure=fig) # 绿色
#
# x = point_s2[:, 0]
# y = point_s2[:, 1]
# z = point_s2[:, 2]
# mlab.points3d(x, y, z, x, mode="point", color=(1, 0, 0), figure=fig) # 红色
# mlab.show()
# 拼接可视化
points = np.concatenate([points, point_s2], axis=0)
print(points.shape)
x = points[:, 0]
y = points[:, 1]
z = points[:, 2]
fig = mlab.figure(bgcolor=(0, 0, 0), size=(640, 640))
mlab.points3d(x, y, z, y, mode="point", figure=fig)
mlab.show()
if __name__ == '__main__':
open3d_registration()