演習問題解答「三次元点群処理 Pythonによる基礎アルゴリズムの実装」

三次元点群処理 Pythonによる基礎アルゴリズムの実装を読みながら、演習問題の解答を記録していきます. 解答はあくまで僕が考えた物なので、合っているかは保証できませんが、参考にはなると思います.(間違い等あればご指摘ください)

第一章 はじめに

問題 1.1

2次元画像ではできないが、3次元データであれば可能になることを3つ述べる.

  • 建設現場の3次元測量
  • 空気抵抗の計算
  • 3Dゲームへの組み込み

問題 1.2

下の右図のような直線で分離不能な2次元データも、3次元空間に拡張すると分離可能な平面が出現する.そのような変数 zz と分離平面の例を挙げる.

sampleData

目的変数が 00 の点を z=1z= -1 、目的変数が 11 の点を z=1z=1 に設定したときの、 z=0z=0 の平面が分離平面となる.

問題 1.3

次元の呪いとは何か?
次元が増えるほど、必要なデータ量が指数関数的に増加してしまうこと.

問題 1.4

身近な製品に搭載されている3次元センサー

スマートフォン

  • LiDARセンサー
  • フォトグラメトリ

ロボット掃除機

  • ToFセンサー
  • VSLAM

自動車

  • LiDARセンサー

問題 1.5

基本的にはベースラインが大きくなるほど精度が向上するが、極端に大きくなると逆に精度が低下しそう.

第二章 点群処理の基礎

問題 2.1

インターネットから3次元データを入手し、Microsoft 3D Builderで描画する.

show-3d-data

お借りした3次元データ

問題 2.2

zxzzxz 系のオイラー角 α,β,γ\alpha, \beta, \gamma を用いて回転行列 RR を求める.

solution_2-2

問題 2.3

回転行列を四元数で表現する.

solution_2-3

問題 2.4

並進と回転の処理の順番を変えると結果は変わるか?

ソースコード
import numpy as np
import open3d as o3d
import copy


mesh = o3d.geometry.TriangleMesh.create_coordinate_frame()

# 並進
t = [.5, .7, 1]
mesh_t = copy.deepcopy(mesh).translate(t)

# 回転
R = o3d.geometry.get_rotation_matrix_from_yxz([np.pi/3, 0,0])
print ("R: ", np.round(R, 7))

R = o3d.geometry.get_rotation_matrix_from_axis_angle([0, np.pi/3, 0])
print ("R: ", np.round(R, 7))

R = o3d.geometry.get_rotation_matrix_from_quaternion([np.cos(np.pi/6), 0, np.sin(np.pi/6), 0])
print ("R: ", np.round(R, 7))

mesh_r = copy.deepcopy(mesh_t)
mesh_r.rotate(R, center=[0,0,0])

print("Type q to continue.")
o3d.visualization.draw_geometries([mesh, mesh_t]) # 並進 -> 回転

# 回転と並進
T = np.eye(4)
T[:3, :3] = R
T[:3, 3] = t 
mesh_r = copy.deepcopy(mesh).transform(T)
print("Type q to continue.")
o3d.visualization.draw_geometries([mesh, mesh_r]) # 回転 -> 並進
solution_2-4

並進に関して

この例だと絶対座標で並進しているため、最終的な物体の位置は変化しない.

回転に関して

回転時の基準となる原点との相対位置が並進により変化しているため、回転の結果も変化する.

問題 2.5 ~ 2.7

実装が書けない😭そもそもOpen3Dとか初めてつかったし!分かるわけないやろ

未来の自分へ

頑張ってください.