📝
Open3Dの視点のあれこれ(ViewControl編)
1. はじめに
「詳解 3次元点群処理 Pythonによる基礎アルゴリズムの実装」というとても良い本があるが、この本を読む前にいくつか必要だった前提知識
Open3Dを使っている人との情報交換用で間違っていることが書いてあったら是非教えていただけると助かります。
- 詳解 3次元点群処理 Pythonによる基礎アルゴリズムの実装
- 著:金崎 朝子 著:秋月 秀一 著:千葉 直也
2. 基礎知識
2.1 Open3Dは右手系、左手系
- Open3Dは右手系
- デフォルトでは、X(赤/水平)、Y(緑/高さ)、Z(青/奥行き)となる。Zが高さになっているので注意する。
2.2 ViewControlの仕組み
Open3Dのカメラの取り扱い ViewControl編 に詳しく書かれている。(ありがとうございます) fovはまだよく理解できていない。(変えどころがわからない)
2.3 Coordinate Frame
Coordinate Frame (日本語だとなんだろう、座標枠?)
点群を表示するときに一緒に出すと良い。RGBの順で赤(R)がX,緑(G)がY,青(B)となっている。
なんとなく、XYZで、水平(X)、奥行き(Y)、高さ(Z)とイメージしたいところだが、Open3Dのデフォルトは高さがY(何か理由があるんだろうけどなんで?)
(あとで絵をつける)
2.4 単位ベクトル(Unit Vector)
front
とかで指定するのは、単位ベクトル(Unit Vector)で、ノルムが1([0.71,0,0.71]
で良いように思う。
..と思ったんだけど、X少し移動させるときは = [0.2,0.0,0.0]
とかでノルムが1にはならないけどこれは考え方が間違えているのだろうか?
3. ViewControlを使った視点の制御
3.1 サンプルデータ
#!/usr/bin/env python
import open3d.data
import open3d as o3d
import numpy as np
# サンプルデータのファイルのパス(~/open3d_data/以下にデータがダウンロードされる)
bunny_path = open3d.data.BunnyMesh().path
# 点群として読み込む
point_cloud = o3d.io.read_point_cloud(bunny_path)
# 点群をnumpyのarrayとして取り出す
points = np.asarray(point_cloud.points)
# 最小値・最大値を求める。
x_min, y_min, z_min = np.min(points, axis=0)
x_max, y_max, z_max = np.max(points, axis=0)
# サイズを計測
size_x = x_max - x_min
size_y = y_max - y_min
size_z = z_max - z_min
# 座標の矢印を作成、大きさをZ軸の大きさに拡大する。
coordinate_frame = o3d.geometry.TriangleMesh.create_coordinate_frame(size=size_z)
# 移動する距離を計算、各軸の点群の最小値 + 寸法の半分 (0,0,0)が中心になるように
move_x = (x_min + size_x/2) * -1
move_y = (y_min + size_y/2) * -1
move_z = (z_min + size_z/2) * -1
# 移動用の行列を作成
# [1,0,0,x]
# [0,1,0,y]
# [0,0,1,z]
# [0,0,0,1]
move_matrix = np.eye(4)
move_matrix[:3, 3] = [move_x,move_y,move_z]
# 移動
point_cloud.transform(move_matrix)
3.2 デフォルト
o3d.visualization.draw_geometries([point_cloud, coordinate_frame])
以下 up=[0,0,0]
, front=[0,0,0]
を変更してさまざまな視点から点群を表示する。
3.3 横
o3d.visualization.draw_geometries([point_cloud, coordinate_frame],
lookat=[0,0,0],
front=[0,0,-1],
zoom=1,
up=[0,1,0])
o3d.visualization.draw_geometries([point_cloud, coordinate_frame],
lookat=[0,0,0],
front=[1,0,0],
zoom=1,
up=[0,1,0])
o3d.visualization.draw_geometries([point_cloud, coordinate_frame],
lookat=[0,0,0],
front=[-1,0,0],
zoom=1,
up=[0,1,0])
3.4 真上から
o3d.visualization.draw_geometries([point_cloud, coordinate_frame],
lookat=[0,0,0],
front=[0,1,0],
zoom=1,
up=[1,0,0])
o3d.visualization.draw_geometries([point_cloud, coordinate_frame],
lookat=[0,0,0],
front=[0,1,0],
zoom=1,
up=[-1,0,0])
o3d.visualization.draw_geometries([point_cloud, coordinate_frame],
lookat=[0,0,0],
front=[0,1,0],
zoom=1,
up=[0,0,1])
o3d.visualization.draw_geometries([point_cloud, coordinate_frame],
lookat=[0,0,0],
front=[0,1,0],
zoom=1,
up=[0,0,-1])
3.5 真下から
o3d.visualization.draw_geometries([point_cloud, coordinate_frame],
lookat=[0,0,0],
front=[0,-1,0],
zoom=1,
up=[1,0,0])
o3d.visualization.draw_geometries([point_cloud, coordinate_frame],
lookat=[0,0,0],
front=[0,-1,0],
zoom=1,
up=[-1,0,0])
3.6 斜め
o3d.visualization.draw_geometries([point_cloud, coordinate_frame],
lookat=[0,0,0],
front=[0.71,0,0.71],
zoom=1,
up=[0,1,0])
o3d.visualization.draw_geometries([point_cloud, coordinate_frame],
lookat=[0,0,0],
front=[0.577,0.577,0.577],
zoom=1,
up=[0,1,0])
o3d.visualization.draw_geometries([point_cloud, coordinate_frame],
lookat=[0,0,0],
front=[0.577,0.577,0.577],
zoom=1,
up=[1,0,0])
3.7 おかしな視点を設定した場合
o3d.visualization.draw_geometries([point_cloud, coordinate_frame],
lookat=[0,0,0],
front=[0,1,0],
zoom=1,
up=[0,1,0])
Discussion