如何使用Open3D:使用FPFH功能进行注册


探索可以使用python处理点云的Open3D。

点云特征与FPFH对齐,并通过ICP进行较小的更正。
-我试图使官方教程更易于阅读。
-由于数值是硬编码,因此我尝试根据点云大小的1/10确定其他各种参数。
-由于方法名称较长,因此import as较短而

提示:
--RANSAC不能正常工作,除非将下采样大小减小到大约1/10。 (大约1/100不能太好)
-FPFH的大小为1/10 * 50。更大的似乎更好。 (因为如果太小,用于特征计算的点数将减少)
-正常计算为1/10,但效果不大。

的open3d

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import sys
sys.path.append("../..") # Open3D/build/lib/ へのパス
import copy
import numpy as np
import py3d
from py3d import registration_ransac_based_on_feature_matching as RANSAC
from py3d import registration_icp as ICP
from py3d import compute_fpfh_feature as FPFH


def show(model, scene, model_to_scene_trans=np.identity(4)):
    model_t = copy.deepcopy(model)
    scene_t = copy.deepcopy(scene)

    model_t.paint_uniform_color([1, 0, 0])
    scene_t.paint_uniform_color([0, 0, 1])

    model_t.transform(model_to_scene_trans)

    py3d.draw_geometries([model_t, scene_t])


model = py3d.read_point_cloud("bun000.ply")
scene = py3d.read_point_cloud("bun045.ply")
## PCLモデルを使うならこちら
#model = py3d.read_point_cloud("milk.pcd")
#scene = py3d.read_point_cloud("milk_cartoon_all_small_clorox.pcd")

# いろいろなサイズの元: model点群の1/10を基本サイズsizeにする
size = np.abs((model.get_max_bound() - model.get_min_bound())).max() / 10
kdt_n = py3d.KDTreeSearchParamHybrid(radius=size, max_nn=50)
kdt_f = py3d.KDTreeSearchParamHybrid(radius=size * 50, max_nn=50)

py3d.estimate_normals(model, kdt_n)
py3d.estimate_normals(scene, kdt_n)
show(model, scene)

# ダウンサンプリング
model_d = py3d.voxel_down_sample(model, size)
scene_d = py3d.voxel_down_sample(scene, size)
py3d.estimate_normals(model_d, kdt_n)
py3d.estimate_normals(scene_d, kdt_n)
show(model_d, scene_d)

# 特徴量計算
model_f = FPFH(model_d, kdt_f)
scene_f = FPFH(scene_d, kdt_f)

# 準備
checker = [py3d.CorrespondenceCheckerBasedOnEdgeLength(0.9),
           py3d.CorrespondenceCheckerBasedOnDistance(size * 2)]

est_ptp = py3d.TransformationEstimationPointToPoint()
est_ptpln = py3d.TransformationEstimationPointToPlane()

criteria = py3d.RANSACConvergenceCriteria(max_iteration=40000,
                                          max_validation=500)
# RANSACマッチング
result1 = RANSAC(model_d, scene_d,
                 model_f, scene_f,
                 max_correspondence_distance=size * 2,
                 estimation_method=est_ptp,
                 ransac_n=4,
                 checkers=checker,
                 criteria=criteria)
show(model_d, scene_d, result1.transformation)

# ICPで微修正
result2 = ICP(model, scene, size, result1.transformation, est_ptpln)
show(model, scene, result2.transformation)

结果

以下结果适用于1/30的大小。 (1/10使它更粗糙)

bunny

原始点云
スクリーンショット 2018-03-26 16.02.28.png
下采样后
スクリーンショット 2018-03-26 16.02.33.png
在RANSAC匹配后
スクリーンショット 2018-03-26 16.02.38.png
ICP之后
スクリーンショット 2018-03-26 16.02.43.png

PCL表牛奶数据

原始点云
スクリーンショット 2018-03-26 16.01.20.png
下采样后
スクリーンショット 2018-03-26 16.01.30.png
在RANSAC匹配后
スクリーンショット 2018-03-26 16.01.50.png
ICP之后
スクリーンショット 2018-03-26 16.02.02.png