一、关于环境
请参考:pymeshlab遍历文件夹中模型、缩放并导出指定格式-CSDN博客
二、关于代码
本文所给出代码仅为参考,禁止转载和引用,仅供个人学习。 本文所给出的例子是https://download.csdn.net/download/weixin_42605076/89233917中的obj_000001.ply。
实际应用中,很少能遇到使用meshlab的点云配准,但对于一些三维重建、位姿估计等应用场景,ICP是必不可少的函数。
第一段代码的目的是旋转、平移物体以模拟两个不对齐的物体模型。
# pymeshlab需要导入,其一般被命名为ml
import pymeshlab as ml
# numpy需要导入,其一般被命名为np
import numpy as np
# 本案例所使用的3D模型为压缩包中的obj_000001.ply,请将其与本脚本放置在同一文件夹内。
input_file = 'obj_000001.ply'
# 首先需要创建一个空的容器
mesh = ml.MeshSet()
# 然后,加载物体模型
mesh.load_new_mesh(input_file)
# 沿着x轴旋转10°
mesh.transform_rotate(
rotaxis = 'X axis',
angle = 10,
)
# 设置移动中心
customcenter = np.array([0, 0, 15], dtype=np.float64)
# 移动模型
mesh.transform_translate_center_set_origin(traslmethod = 'XYZ translation',
axisx = customcenter[0],
axisy = customcenter[1],
axisz = customcenter[2],
)
# 保存
mesh.save_current_mesh(input_file.replace('.ply', '_rot.ply'), save_vertex_normal = True, binary = False)
第二段代码的目的是加载平移旋转前后的两个物体模型并调用ICP算法来微调物体。
# pymeshlab需要导入,其一般被命名为ml
import pymeshlab as ml
# numpy需要导入,其一般被命名为np
import numpy as np
# 本案例所使用的3D模型为压缩包中的obj_000001.ply,请将其与本脚本放置在同一文件夹内。
input_file_1 = 'obj_000001.ply'
# 本案例所使用obj_000001_rot.ply是根据上一个脚本生成的,请将其与本脚本放置在同一文件夹内。
input_file_2 = 'obj_000001_rot.ply'
# 首先需要创建一个空的容器
mesh = ml.MeshSet()
# 然后,加载物体模型1
mesh.load_new_mesh(input_file_1)
# 然后,加载物体模型2
mesh.load_new_mesh(input_file_2)
# MeshLab过滤器名称:“ICP Between Meshes” 执行ICP算法以最小化两个点云之间的差异。
mesh.icp_between_meshes(
referencemesh = 0, # 参考网格:参考网格是ICP过程中保持固定的点云。
sourcemesh = 1, # 源网格:源网格是将进行旋转平移以匹配参考网格的点云。
samplenum = 2000, # 样本数量:我们在每次ICP迭代中尝试选择的样本数量
mindistabs = 10, # 最小起始距离:对于一个网格上的所有选定样本,我们只考虑ICP中接近该值的样本。如果MSD太大,可以包括异常值,如果它太小,收敛会非常慢。这里需要一个很好的猜测,建议值在设备扫描误差的10-100倍范围内。此值也会通过“减小距离系数”动态更改
trgdistabs = 0.005, # 目标距离:当50%的选定样本低于该距离时,我们认为两个网格对齐。通常,它应该是一个低于扫描设备误差的值。
maxiternum = 75, # 最大迭代次数:允许ICP执行的最大迭代次数。
samplemode = True, # 法线均衡采样:如果为true(默认值),则选择的icp采样点的分布相对于曲面的法线是均匀的。否则,它们以空间均匀的方式分布。
reducefactorperc = 0.8, # MSD减小系数:在每次ICP迭代中,最小起始距离减小为样本距离百分位数的5倍(例如,如果RF为0.9,则新的最小起始距离为该值的5倍,使得90%的样本位于低于的距离处。
passhifilter = 0.75, # 样本切割高:在每次ICP迭代中,所有超过百分位数的样本都会被丢弃(在实践中,我们只使用最佳结果)。
matchmode = True, # 刚性匹配:如果为true,则ICP仅通过旋转平移执行匹配(不允许缩放)。如果为false,则允许更宽松的变换矩阵(可能出现缩放和剪切)。
savelastiteration = False, # 保存最后一次迭代:切换此复选框以保存两层中的最后迭代点。
)
# 合并物体1和物体2
mesh.flatten_visible_layers()
# 保存
mesh.save_current_mesh(input_file_1.replace('.ply', '_merge.ply'), save_vertex_normal = True, binary = False)