Вот код Python, который я использовал:
Код: Выделить всё
import open3d as o3d
import numpy as np
def load_point_clouds(ply_files):
pcds = []
for file in ply_files:
pcd = o3d.io.read_point_cloud(file)
pcd.estimate_normals(search_param=o3d.geometry.KDTreeSearchParamHybrid(radius=0.1, max_nn=30))
pcds.append(pcd)
return pcds
def pairwise_registration(source, target):
print("Apply point-to-point ICP")
icp_coarse = o3d.pipelines.registration.registration_icp(
source, target, 0.1, np.identity(4),
o3d.pipelines.registration.TransformationEstimationPointToPoint())
icp_fine = o3d.pipelines.registration.registration_icp(
source, target, 0.05, icp_coarse.transformation,
o3d.pipelines.registration.TransformationEstimationPointToPoint())
print("Apply point-to-plane ICP")
icp_coarse = o3d.pipelines.registration.registration_icp(
source, target, 0.1, icp_fine.transformation,
o3d.pipelines.registration.TransformationEstimationPointToPlane())
icp_fine = o3d.pipelines.registration.registration_icp(
source, target, 0.05, icp_coarse.transformation,
o3d.pipelines.registration.TransformationEstimationPointToPlane())
transformation_icp = icp_fine.transformation
information_icp = o3d.pipelines.registration.get_information_matrix_from_point_clouds(
source, target, 0.05, icp_fine.transformation)
return transformation_icp, information_icp
def full_registration(pcds):
pose_graph = o3d.pipelines.registration.PoseGraph()
odometry = np.identity(4)
pose_graph.nodes.append(o3d.pipelines.registration.PoseGraphNode(odometry))
for target_id in range(1, len(pcds)):
transformation_icp, information_icp = pairwise_registration(pcds[0], pcds[target_id])
odometry = np.dot(transformation_icp, odometry)
pose_graph.nodes.append(o3d.pipelines.registration.PoseGraphNode(np.linalg.inv(odometry)))
pose_graph.edges.append(o3d.pipelines.registration.PoseGraphEdge(0, target_id,
transformation_icp, information_icp,
uncertain=False))
return pose_graph
def merge_point_clouds(ply_files):
pcds = load_point_clouds(ply_files)
print("Full registration ...")
pose_graph = full_registration(pcds)
print("Optimizing PoseGraph ...")
option = o3d.pipelines.registration.GlobalOptimizationOption(max_correspondence_distance=0.05,
edge_prune_threshold=0.25,
reference_node=0)
o3d.pipelines.registration.global_optimization(pose_graph,
o3d.pipelines.registration.GlobalOptimizationLevenbergMarquardt(),
o3d.pipelines.registration.GlobalOptimizationConvergenceCriteria(),
option)
print("Transform points and display")
for point_id in range(len(pcds)):
print(pose_graph.nodes[point_id].pose)
pcds[point_id].transform(pose_graph.nodes[point_id].pose)
# Rotate the second point cloud by 180 degrees around the Z axis
'''rotation_matrix = np.array([[ -1, 0, 0, 0],
[ 0, -1, 0, 0],
[ 0, 0, 1, 0],
[ 0, 0, 0, 1]])
pcds[1].transform(rotation_matrix)'''
pcd_combined = o3d.geometry.PointCloud()
for pcd in pcds:
pcd_combined += pcd
pcd_combined_down = pcd_combined.voxel_down_sample(voxel_size=0.005)
o3d.io.write_point_cloud("merged_point_cloud.ply", pcd_combined_down)
print("Merged point cloud saved as merged_point_cloud.ply")
ply_files = [
"/content/test_0.ply",
"/content/test_1.ply",
# Add more point cloud files as needed
]
merge_point_clouds(ply_files)
Приведенный выше код преобразует и объединяет второе облако точек с первым облаком точек, не выравнивая их должным образом. В результате объединенное облако точек неточно отражает всю кучу песка.
Что мне нужно:
Я ищу предложения о том, как правильно объединить эти два облака точек с помощью Python. В идеале окончательное облако точек должно точно представлять всю кучу песка с правильным выравниванием двух частей.
Дополнительная информация:
Файлы облака точек имеют формат .ply.
Я использую библиотеку open3d для обработки облаков точек.
Ожидается, что выравнивание будет выполняться с использованием алгоритма ICP или любого другого подходящего метода, который обеспечивает правильное объединение облаков точек.
Я ценю любую помощь или рекомендации о том, как решить эту проблему и добиться желаемого слияния облаков точек.
Подробнее здесь: https://stackoverflow.com/questions/787 ... -algorithm