目录
一、概述
1.1原理和步骤
1.2关键技术和优势
1.3应用场景
二、代码实现
2.1 关键代码
2.1.1.函数:execute_fast_global_registration
2.1.2调用registration_fgr_based_on_feature_matching函数
2.2完整代码
三、实现效果
3.1原始点云
3.2粗配准后点云
一、概述
Open3D中的Fast Global Registration(快速全局配准)是一种基于特征匹配的快速点云配准算法,旨在有效地将两个点云快速对齐,以提供初步的配准结果。以下是Fast Global Registration的原理和关键步骤:
1.1原理和步骤
1.特征计算:
对输入的源点云和目标点云计算全局特征描述符。通常使用的特征包括FPFH(Fast Point Feature Histograms)或SHOT(Signature of Histograms of Orientations)。
特征描述符捕捉了点云局部几何结构的信息,对点云的形状和曲率变化有很好的描述能力。
2.特征匹配:
利用计算得到的全局特征描述符进行点云之间的特征匹配。这一步旨在找到源点云和目标点云中具有相似局部几何结构的点对。
3.快速全局配准:
使用匹配到的特征点对进行快速全局配准。Open3D中的Fast Global Registration算法实现了一种高效的配准策略,可以在短时间内获得粗略但有效的全局配准结果。
4.优化:
为了进一步提升配准精度,可以在快速全局配准的基础上进行后续的优化步骤,如ICP(Iterative Closest Point)算法或更精确的局部优化。
1.2关键技术和优势
- 高效性:Fast Global Registration算法在保证一定配准质量的前提下,尽可能地减少计算时间,适合于处理大规模点云数据。
- 特征描述符:利用全局特征描述符可以有效地捕捉点云的局部特征信息,避免了传统方法中对全局搜索的依赖,加快了配准过程。
- RANSAC:算法内部可能会使用RANSAC(随机采样一致性)算法来估计初始的变换参数,以应对部分匹配或噪声的影响。
1.3应用场景
Fast Global Registration适用于需要快速处理大规模点云数据并获得初步对齐结果的场景,例如机器人感知、三维重建、虚拟现实和增强现实等领域。它为后续更精细的点云配准和分析提供了良好的初始对齐结果,有助于提升整体系统的效率和准确性。
二、代码实现
2.1 关键代码
这段代码实现了基于特征匹配的快速全局配准(Fast Global Registration,FGR)过程:
# --------------------------------------------FastGlobalRegistration配准----------------------------------------------
def execute_fast_global_registration(source, target, source_fpfh, target_fpfh): # 传入两个点云和点云的特征
distance_threshold = 0.5 # 设定距离阈值
print(":: Apply fast global registration with distance threshold %.3f" \
% distance_threshold)
result = o3d.pipelines.registration.registration_fgr_based_on_feature_matching(
source, target, source_fpfh, target_fpfh,
o3d.pipelines.registration.FastGlobalRegistrationOption(
maximum_correspondence_distance=distance_threshold))
return result
2.1.1.函数:execute_fast_global_registration
def execute_fast_global_registration(source, target, source_fpfh, target_fpfh):
distance_threshold = 0.5 # 设定距离阈值
print(":: Apply fast global registration with distance threshold %.3f" % distance_threshold)
参数:
- source:源点云对象。
- target:目标点云对象。
- source_fpfh:源点云的FPFH特征。
- target_fpfh:目标点云的FPFH特征。
2.1.2调用registration_fgr_based_on_feature_matching函数
result = o3d.pipelines.registration.registration_fgr_based_on_feature_matching(
source, target, source_fpfh, target_fpfh,
o3d.pipelines.registration.FastGlobalRegistrationOption(
maximum_correspondence_distance=distance_threshold))
参数解释:
- source 和 target:需要配准的源点云和目标点云。
- source_fpfh 和 target_fpfh:源点云和目标点云的FPFH特征。
- FastGlobalRegistrationOption:指定了快速全局配准的参数选项。
- maximum_correspondence_distance:最大对应点距离阈值。该阈值用于筛选特征匹配点对,超过该距离的点对将被忽略。
2.2完整代码
import open3d as o3d
import time
import copy
# ----------------------------------------------传入点云数据,计算FPFH-------------------------------------------------
def fpfh_compute(pcd):
radius_normal = 0.01 # kdtree参数,用于估计法线的半径,
print(":: Estimate normal with search radius %.3f." % radius_normal)
pcd.estimate_normals(
o3d.geometry.KDTreeSearchParamHybrid(radius=radius_normal, max_nn=30))
# 估计法线的1个参数,使用混合型的kdtree,半径内取最多30个邻居
radius_feature = 0.025 # kdtree参数,用于估计FPFH特征的半径
print(":: Compute FPFH feature with search radius %.3f." % radius_feature)
# 计算FPFH特征,搜索方法kdtree
pcd_fpfh = o3d.pipelines.registration.compute_fpfh_feature(pcd,
o3d.geometry.KDTreeSearchParamHybrid
(radius=radius_feature, max_nn=50))
return pcd_fpfh # 返回FPFH特征
# --------------------------------------------FastGlobalRegistration配准----------------------------------------------
def execute_fast_global_registration(source, target, source_fpfh, target_fpfh): # 传入两个点云和点云的特征
distance_threshold = 0.5 # 设定距离阈值
print(":: Apply fast global registration with distance threshold %.3f" \
% distance_threshold)
result = o3d.pipelines.registration.registration_fgr_based_on_feature_matching(
source, target, source_fpfh, target_fpfh,
o3d.pipelines.registration.FastGlobalRegistrationOption(
maximum_correspondence_distance=distance_threshold))
return result
# ---------------------------------------------------可视化配准结果----------------------------------------------------
def draw_registration_result(source, target, transformation):
source_temp = copy.deepcopy(source) # 由于函数transformand paint_uniform_color会更改点云,
target_temp = copy.deepcopy(target) # 因此调用copy.deepcoy进行复制并保护原始点云。
source_temp.paint_uniform_color([1, 0, 0]) # 点云着色
target_temp.paint_uniform_color([0, 1, 0])
source_temp.transform(transformation)
# o3d.io.write_point_cloud("trans_of_source.pcd", source_temp) # 保存配准后的点云
o3d.visualization.draw_geometries([source_temp, target_temp], width=600, height=600, mesh_show_back_face=False)
if __name__ == "__main__":
# --------------------读取点云数据------------------
source = o3d.io.read_point_cloud("..//..//standford_cloud_data//hand_trans.pcd")
target = o3d.io.read_point_cloud("..//..//standford_cloud_data//hand.pcd")
source = source.uniform_down_sample(every_k_points=10)
target = target.uniform_down_sample(every_k_points=10)
start = time.time()
# -----------计算源点云和目标点云的FPFH-------------
source_fpfh = fpfh_compute(source)
target_fpfh = fpfh_compute(target)
# ------------------调用FGR执行粗配准----------------
result_fast = execute_fast_global_registration(source, target,
source_fpfh, target_fpfh)
print("Fast global registration took %.3f sec.\n" % (time.time() - start))
print(result_fast)
draw_registration_result(source, target, result_fast.transformation) # 源点云旋转平移到目标点云