見出し画像

Open3Dで点群数を減らしてみた

技術検証をするハードルが低くなった


今までいろいろな仕事をしてきているがプログラムをかじり始めたら
自分でも検証してみようという気持ちになった

というか

今まではやってみようという気持ちにもならなかったし
考えもしなかったので、会社のプログラマーにこれできる?
という感じで聞くだけだったり
ググって検索してできそうだなと検証するくらいだった

プログラミングすることには、見えない心理的なハードルがあった

それがなくなっただけでもやった価値がある

ということで

今回は相談があったある建物の点群ファイルの点群数を減らしてブラウザで動かしやすくするという課題を自分でチャレンジしてみる

Open3Dでできる主なこと

  • ポイントクラウド処理:

    • ノイズ除去、サンプリング、ダウンサンプリング、フィルタリング。

  • メッシュ処理:

  • ボクセル処理:

  • RGB-Dデータ処理:

  • ビジュアライゼーション:

  • 幾何計算:

  • 高度なアルゴリズム:

  • 機械学習のサポート:

色々できそうですがダウンサンプリングをやってみたい


Open3Dで点群数を減らすダウンサンプリングの手順

  • フリーのPLYファイルを探す

  • macのローカルでvscodeを使う

  • Open3Dをインストール

  • vscodeでコーディング


フリーのPLYファイルを探す

フリーのPLYを探しました。これはMeshlabで表示しています。

オートバイ 出典 Artec 3D

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

すごっ


open3dのウィンドウ


拡大するとこんな感じ


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
voxel_size = 20.0 point cloud = 25384

思い切って
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

見た目はあまりわからん


voxel_size = 100.0 point cloud = 799

まとめ

Open3DでPLYファイルのポイントクラウドの数を減らすことができました。

Number of points in the original point cloud: 520245
Number of points in the downsampled point cloud: 799

上記の場合サイズも44MBから19KBへ小さくなりました。

サイズも小さくなる


このように時間は実際かかってしまったけど、理論上でわかることと実際にプログラム上で動かすことは全然違う。

もっと深く色々理解しようという気になる。

おもしろ

何かで活用できれば良いかな


この記事が気に入ったらサポートをしてみませんか?