![見出し画像](https://assets.st-note.com/production/uploads/images/142320237/rectangle_large_type_2_d95d7b90841e166c45d34522a0d959fa.png?width=1200)
Open3Dで点群数を減らしてみた
技術検証をするハードルが低くなった
今までいろいろな仕事をしてきているがプログラムをかじり始めたら
自分でも検証してみようという気持ちになった
というか
今まではやってみようという気持ちにもならなかったし
考えもしなかったので、会社のプログラマーにこれできる?
という感じで聞くだけだったり
ググって検索してできそうだなと検証するくらいだった
プログラミングすることには、見えない心理的なハードルがあった
それがなくなっただけでもやった価値がある
ということで
今回は相談があったある建物の点群ファイルの点群数を減らしてブラウザで動かしやすくするという課題を自分でチャレンジしてみる
Open3Dでできる主なこと
ポイントクラウド処理:
ノイズ除去、サンプリング、ダウンサンプリング、フィルタリング。
メッシュ処理:
ボクセル処理:
RGB-Dデータ処理:
ビジュアライゼーション:
幾何計算:
高度なアルゴリズム:
機械学習のサポート:
色々できそうですがダウンサンプリングをやってみたい
Open3Dで点群数を減らすダウンサンプリングの手順
フリーのPLYファイルを探す
macのローカルでvscodeを使う
Open3Dをインストール
vscodeでコーディング
フリーのPLYファイルを探す
フリーのPLYを探しました。これはMeshlabで表示しています。
![](https://assets.st-note.com/img/1717036334579-cWHb7xQmeq.png?width=1200)
VSCodeの新規プロジェクトでターミナルを開く
仮想環境を作成
python3 -m venv venv
仮想環境を有効化
source venv/bin/activate
Open3Dをインストール
pip install open3d
python3.12.3だとインストールできなかったので
python3.10にダウングレードしたらインストールできました。
仮想環境も作り直します。
まずはPLYファイルでポイントクラウド数を表示してみる
check_point_cloud.py
import open3d as o3d
try:
# PLYファイルを読み込む
pcd = o3d.io.read_point_cloud("/Users/kawamotonaoki/Desktop/motorbike-ply/Motorbike_ply.ply")
# ポイントクラウドのポイント数を取得
num_points = len(pcd.points)
print(f"Number of points in the point cloud: {num_points}")
except Exception as e:
print(f"An error occurred: {e}")
python check_point_cloud.py
結果 520245
Number of points in the point cloud: 520245
ボクセルサイズとポイントクラウドの関係
ポイントクラウドは、3D空間内の多数の点(ポイント)で物体の表面を表現する方法
ボクセル(voxel)は「volume element(体積要素)」の略で、3D空間を小さな立方体(グリッド)に分割して表現する方法
ボクセルサイズが小さい:ポイントクラウドの各ボクセル(立方体セル)のサイズが小さくなると、同じ空間内により多くのボクセルが配置されるため、ポイントクラウド内のポイント数はあまり減らない
ボクセルサイズが大きい:ボクセルのサイズが大きくなると、同じ空間内に配置されるボクセルの数が減少するため、ポイントクラウド内のポイント数は大幅に減る
次にMotorbike_ply_plyを表示してみる
display_point_cloud.pyというファイルを作る
import open3d as o3d
# PLYファイルを読み込む
pcd = o3d.io.read_point_cloud("/Users/kawamotonaoki/Desktop/motorbike-ply/Motorbike_ply.ply")
# ポイントクラウドを可視化する
o3d.visualization.draw_geometries([pcd],
zoom=0.5,
front=[0.0, 0.0, -1.0],
lookat=[0.0, 0.0, 0.0],
up=[0.0, 1.0, 0.0])
python display_point_cloud.py
すごっ
![](https://assets.st-note.com/img/1717038769429-e1FMkdQWkk.png?width=1200)
![](https://assets.st-note.com/img/1717038793087-5VtCiKhlcq.png?width=1200)
Open3Dでダウンサンプリング
downsample_point_cloud.pyファイルを作成
import open3d as o3d
# PLYファイルを読み込む
pcd = o3d.io.read_point_cloud("/Users/kawamotonaoki/Desktop/motorbike-ply/Motorbike_ply.ply")
# ダウンサンプリングする(ボクセルサイズを指定)
voxel_size = 0.02 # 例:0.02メートルのボクセルサイズ
downsampled_pcd = pcd.voxel_down_sample(voxel_size)
# オリジナルのポイントクラウドのポイント数を取得
original_num_points = len(pcd.points)
print(f"Number of points in the original point cloud: {original_num_points}")
# ダウンサンプリングされたポイントクラウドのポイント数を取得
downsampled_num_points = len(downsampled_pcd.points)
print(f"Number of points in the downsampled point cloud: {downsampled_num_points}")
# ダウンサンプリングされたポイントクラウドを保存する
o3d.io.write_point_cloud("Motorbike_downsampled_file.ply", downsampled_pcd)
# ダウンサンプリングされたポイントクラウドを可視化する
o3d.visualization.draw_geometries([downsampled_pcd],
zoom=0.5,
front=[0.0, 0.0, -1.0],
lookat=[0.0, -1.0, 0.0], # -1.0の値を調整して下の方に表示
up=[0.0, 1.0, 0.0])
結果:あまり変わらない
python downsample_point_cloud.py
Number of points in the original point cloud: 520245
Number of points in the downsampled point cloud: 520244
もっと減らす
voxel_size = 10.0 ボクセルサイズで調整できるらしい多く減らした場合はこの値を大きくする
ボクセルのサイズが大きくなると、同じ空間内に配置されるボクセルの数が減少するため、ポイントクラウド内のポイント数は大幅に減る
downsample_point_cloud.pyファイルを更新
import open3d as o3d
# PLYファイルを読み込む
pcd = o3d.io.read_point_cloud("/Users/kawamotonaoki/Desktop/motorbike-ply/Motorbike_ply.ply")
# オリジナルのポイントクラウドのポイント数を取得
original_num_points = len(pcd.points)
print(f"Number of points in the original point cloud: {original_num_points}")
# ダウンサンプリングする(ボクセルサイズを指定)
voxel_size = 10.0 # ボクセルサイズを大きく設定
downsampled_pcd = pcd.voxel_down_sample(voxel_size)
# ダウンサンプリングされたポイントクラウドのポイント数を取得
downsampled_num_points = len(downsampled_pcd.points)
print(f"Number of points in the downsampled point cloud: {downsampled_num_points}")
# ダウンサンプリングされたポイントクラウドを保存する
o3d.io.write_point_cloud("Motorbike_downsampled_file.ply", downsampled_pcd)
# ダウンサンプリングされたポイントクラウドを可視化する
o3d.visualization.draw_geometries([pcd],
zoom=0.5,
front=[0.0, 0.0, -1.0],
lookat=[0.0, -1.0, 0.0],
up=[0.0, 1.0, 0.0])
$ python downsample_point_cloud.py
Number of points in the original point cloud: 520245
Number of points in the downsampled point cloud: 94400
さらに
voxel_size = 20.0
$ python downsample_point_cloud.py
Number of points in the original point cloud: 520245
Number of points in the downsampled point cloud: 25384
![](https://assets.st-note.com/img/1717041108870-rDBf64jPBq.png?width=1200)
思い切って
voxel_size = 100.0
python downsample_point_cloud.py
Number of points in the original point cloud: 520245
Number of points in the downsampled point cloud: 799
見た目はあまりわからん
![](https://assets.st-note.com/img/1717041916796-Ns7p5uS9ux.png?width=1200)
まとめ
Open3DでPLYファイルのポイントクラウドの数を減らすことができました。
Number of points in the original point cloud: 520245
Number of points in the downsampled point cloud: 799
上記の場合サイズも44MBから19KBへ小さくなりました。
![](https://assets.st-note.com/img/1717041471470-sSTIhKhRPd.png?width=1200)
このように時間は実際かかってしまったけど、理論上でわかることと実際にプログラム上で動かすことは全然違う。
もっと深く色々理解しようという気になる。
おもしろ
何かで活用できれば良いかな