Learning Open3D→Tutorial→上級編→RGBD統合
RGBD統合
Open3DはスケーラブルなRGBD画像統合アルゴリズムを実装している。 このアルゴリズムは Curless(1996)と Newcombe(2011)で提示された手法に基づいている。 大きなシーンをサポートするために、ElasticReconstructionのIntegraterで導入された階層的なハッシュ構造を使用する。
注意: コードを走らせる環境に注意すること。カレント(作業)ディレクトリを(Open3Dの)examples/Python/Advanced
にすること(trajectory_io.py
をインポートするため)
# examples/Python/Advanced/rgbd_integration.py
import open3d as o3d
from trajectory_io import *
import numpy as np
if __name__ == "__main__":
# (1) read trajectory from .log file
camera_poses = read_trajectory("../../TestData/RGBD/odometry.log")
# (2) TSDF volume integration
volume = o3d.integration.ScalableTSDFVolume(
voxel_length=4.0 / 512.0,
sdf_trunc=0.04,
color_type=o3d.integration.TSDFVolumeColorType.RGB8)
for i in range(len(camera_poses)):
print("Integrate {:d}-th image into the volume.".format(i))
color = o3d.io.read_image(
"../../TestData/RGBD/color/{:05d}.jpg".format(i))
depth = o3d.io.read_image(
"../../TestData/RGBD/depth/{:05d}.png".format(i))
rgbd = o3d.geometry.RGBDImage.create_from_color_and_depth(
color, depth, depth_trunc=4.0, convert_rgb_to_intensity=False)
volume.integrate(
rgbd,
o3d.camera.PinholeCameraIntrinsic(
o3d.camera.PinholeCameraIntrinsicParameters.PrimeSenseDefault),
np.linalg.inv(camera_poses[i].pose))
# (3) Extract a mesh
print("Extract a triangle mesh from the volume and visualize it.")
mesh = volume.extract_triangle_mesh()
mesh.compute_vertex_normals()
o3d.visualization.draw_geometries([mesh])
.logファイルから軌跡(trajectory)を読み込む
examples/Python/Advanced/rgbd_integration.py
の最初のコード:
camera_poses = read_trajectory("../../TestData/RGBD/odometry.log")
このチュートリアルでは、関数read_trajectory
を使用して.logファイルからカメラの軌跡を読み込む。 サンプルの.logファイルの内容は次のとおり。
# ../../TestData/RGBD/odometry.log
0 0 1
1 0 0 2
0 1 0 2
0 0 1 -0.3
0 0 0 1
1 1 2
0.999988 3.08668e-005 0.0049181 1.99962
-8.84184e-005 0.999932 0.0117022 1.97704
-0.0049174 -0.0117024 0.999919 -0.300486
0 0 0 1
(以下略)
TSDF (volumetric truncated signed distance function): https://www.slideshare.net/hirokiwaterfield/30th-dynamicfusion や https://github.com/andyzeng/tsdf-fusion 参照
examples/Python/Advanced/rgbd_integration.py
の2番めの部分コード:
# (2) TSDF volume integration
volume = o3d.integration.ScalableTSDFVolume(
voxel_length=4.0 / 512.0,
sdf_trunc=0.04,
color_type=o3d.integration.TSDFVolumeColorType.RGB8)
for i in range(len(camera_poses)):
print("Integrate {:d}-th image into the volume.".format(i))
color = o3d.io.read_image(
"../../TestData/RGBD/color/{:05d}.jpg".format(i))
depth = o3d.io.read_image(
"../../TestData/RGBD/depth/{:05d}.png".format(i))
rgbd = o3d.geometry.RGBDImage.create_from_color_and_depth(
color, depth, depth_trunc=4.0, convert_rgb_to_intensity=False)
volume.integrate(
rgbd,
o3d.camera.PinholeCameraIntrinsic(
o3d.camera.PinholeCameraIntrinsicParameters.PrimeSenseDefault),
np.linalg.inv(camera_poses[i].pose))
Open3Dは、UniformTSDFVolume
とScalableTSDFVolume
という2種類のTSDFボリュームを提供している。 後者は階層構造を使用し、より大きなシーンをサポートするので推奨する。
ScalableTSDFVolume
にはいくつかのパラメータがある。voxel_length = 4.0 / 512.0
は、TSDFボリュームの単一のボクセルサイズが$\frac{4.0m}{512.0} = 7.8125mm$であることを意味する。 この値を小さくすると、高解像度のTSDFボリュームになるが、積分結果が深度ノイズの影響を受けやすくなる。 sdf_trunc = 0.04
は、符号付き距離関数(SDF, Signed Distance Function)の切り捨て(trancated)値を指定する。 with_color = True
の場合、色もTSDFボリュームの一部として統合される。 カラーインテグレーションはPCLに触発されたものである。
メッシュの抽出
メッシュの抽出には Lorensen & Cline(1987)のmarching cubesアルゴリズムを使用している。
Lorensen, W. E. & amp; H. E. Cline(1987) Marching cubes: A high resolution 3d surface construction algorithm, ACM Computer Graphics.
# (3) Extract a mesh
print("Extract a triangle mesh from the volume and visualize it.")
mesh = volume.extract_triangle_mesh()
mesh.compute_vertex_normals()
o3d.visualization.draw_geometries([mesh])
この出力: