RGBD integration

RGBD統合

Open3DはスケーラブルなRGBD画像統合アルゴリズムを実装している。 このアルゴリズムは Curless(1996)と Newcombe(2011)で提示された手法に基づいている。 大きなシーンをサポートするために、ElasticReconstructionのIntegraterで導入された階層的なハッシュ構造を使用する。

  • Curless, B. & Levoy, M. (1996) A volumetric method for building complex models from range images. In SIGGRAPH 1996.
  • Newcombe, R. A., Izadi, S., Hilliges, O., Molyneaux, D., Kim, D., Davison, A. J., Kohli, P., Shotton, J., Hodges, S., & Fitzgibbon, A. (2011). KinectFusion: Real-time dense surface mapping and tracking. In ISMAR 2011.

注意: コードを走らせる環境に注意すること。カレント(作業)ディレクトリを(Open3Dの)examples/Python/Advancedにすること(trajectory_io.pyをインポートするため)

In [3]:
# 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])
Integrate 0-th image into the volume.
Integrate 1-th image into the volume.
Integrate 2-th image into the volume.
Integrate 3-th image into the volume.
Integrate 4-th image into the volume.
Extract a triangle mesh from the volume and visualize it.

Read trajectory from .log file

.logファイルから軌跡(trajectory)を読み込む

examples/Python/Advanced/rgbd_integration.pyの最初のコード:

In [ ]:
    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 volume integration

TSDF (volumetric truncated signed distance function): https://www.slideshare.net/hirokiwaterfield/30th-dynamicfusionhttps://github.com/andyzeng/tsdf-fusion 参照

examples/Python/Advanced/rgbd_integration.pyの2番めの部分コード:

In [ ]:
    # (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は、UniformTSDFVolumeScalableTSDFVolumeという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に触発されたものである。

Extract a mesh

メッシュの抽出

メッシュの抽出には 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.

In [ ]:
    # (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])

この出力:

http://www.open3d.org/docs/release/_images/integrated.png

注意

TSDFボリュームは、3D空間の加重平均フィルターのように機能する。多くのフレームを統合する場合、ボリュームはより滑らかでより良いメッシュを生成する。 その他の例については、フラグメントの作成を参照のこと。

Previous:多方向位置合わせ                  Next:カラーマップ最適化