https://qiita.com/567000/items/094989222854ba5ae951
これの続きです。
もう少しキャッキャッするために調べたことを……。
open3d.geometry.PointCloud とは?
pcd = o3d.io.read_point_cloud("data.xyz")
読み込んだ pcd
は open3d.geometry.PointCloud
型です。
この型から座標を取り出す方法です。
(マニュアルみたら一瞬で解決することなのですが自分用のメモです)
点群を配列(Numpy)としてとりだせる
np.asarray(pcd.points)
これで取り出して Numpy で遊べます。
xyz = np.asarray(pcd.points)
print(xyz)
print(xyz[0])
print(xyz[0][0])
これで普通に配列として扱えるので何でも出来るようになります!
# xyz
[[-22.755951 6.552761 -22.308571]
...
[ 15.542783 -4.47567 -15.237212]]
# xyz[0]
[-22.755951 6.552761 -22.308571]
# xyz[0][0]
-22.755951
逆に Numpy を PointCloud にも出来る
new_pcd = o3d.geometry.PointCloud()
new_pcd.points = o3d.utility.Vector3dVector(data)
読み込んだ PointCloud を Numpy で加工してまた PointCloud に戻す
普通にデータを読み込んで表示するとこうなところを、、、
import open3d as o3d
import numpy as np
pcd = o3d.io.read_point_cloud("vase.xyz")
o3d.visualization.draw_geometries([pcd])
データを1つ1つ見て例えばある範囲内だけのデータをとりだして表示する(切り出す)なんてこともできます。
import open3d as o3d
import numpy as np
pcd = o3d.io.read_point_cloud("vase.xyz")
xyz = np.asarray(pcd.points)
data = np.empty((0,3))
for l in xyz:
x = l[0]
y = l[1]
z = l[2]
if( 0.3>y and y>0.2 ):
data = np.append(data, np.array([[x,y,z]]), axis=0)
new_pcd = o3d.geometry.PointCloud()
new_pcd.points = o3d.utility.Vector3dVector(data)
o3d.visualization.draw_geometries([new_pcd])
これが出来ることで、ノイズ除去とか、ダウンサンプリングとか、Voxel化とか、いろいろできますね!!
(ほとんど PointCloud の標準メソッドにも用意されていますが……自分好みで何かしたいこともあると思うので……)