はじめに
自前のコードは書かずに、なるべく標準に寄せたいと思っている。
ステレオカメラの視差の表示のために視点を変えた画像の生成や、点群データの保存をしたくなったので、Open3Dを使い始めることになった。
そのなかで感じた雑感を記す。
OpenCVでも深度データから点群を作れるけど
- OpenCVにも
- 深度データから点群を生成する関数
- 点群から2Dの画像を生成する関数があります。
- ascii形式のplyファイルを出力することは簡単。
- OpenCV-Python Tutorialsの「カメラ校正」への補足
>>> import cv2
>>> help(cv2.reprojectImageTo3D)
reprojectImageTo3D(...)
reprojectImageTo3D(disparity, Q[, _3dImage[, handleMissingValues[, ddepth]]]) -> _3dImage
. @brief Reprojects a disparity image to 3D space.
ですから、最初のバージョンはOpenCVで書いて見ました。
OpenCV での不安
- OpenCVでの2D-3D関係の関数は少ない。
- そのため自作コードが増えてしまう。
- 品質の確保に不安が出てくる。
Open3Dでの書き換えへの期待
- 自作コードを減らしたい。
- Open3Dが予め用意している枠組みを使ってもっと楽をしたい。
- さまざまなバックエンド対応はOpen3Dのコミュニティに任せられる。
- マルチコア対応、GPU対応、ARM対応など
どう使えばいいらしいのか
- o3d.geometry.PointCloud
- o3d.t.geometry.PointCloud
の2つがある。
o3d.t.geometry.PointCloudが最近の推奨
o3d.geometry.PointCloudはlegacy という位置づけらしい。
o3d.t.geometry.PointCloud型のクラスにはto_legacy()というメソッドがある。
to_legacy() の戻り値は、o3d.geometry.PointCloud 型になる。
o3d.io.write_point_cloud()の関数は、legacyの方の型にしか対応していないようだ。
(この記事の執筆時点では)
だから、次のようなコードとなる。
.py
# legacyの型への変換
pcd = stereo_camera.pcd.to_legacy()
o3d.io.write_point_cloud(str(plyname), pcd, format='auto', write_ascii=False, compressed=False, print_progress=True)
現時点での私の理解
- なるべく、legacyではない方の実装を利用してコードを書く。
- ただ、IO関係で、うまくいかない場合には、to_legacy() してlegacy型に変換して、legacyにあるIOの実装を使った方がいいようだ。
今後使っていきたいもの
- ステレオ計算で生じたartifact(手前の物体と背景の境に生じる不自然極まりない余計な点)を削除したい。
Point cloud outlier removal - メッシュを作成したい。
Mesh
自前の関数で不要になったコードは学習用のコードと割り切る
- OpenCVベースで処理を行えば、行列(np.ndarray型)での明示的な演算をすることになる。
- そのため、depth画像から3Dの点群を生成するには、実際にはどう計算するのかを知るのには適している。
- Open3Dで書き換えていくと、そのような明示的な操作は、Open3Dのライブラリの内部に隠れていく。
- だから、自前の関数で不要になったコードは学習用のコードと割り切る。