![見出し画像](https://assets.st-note.com/production/uploads/images/152141985/rectangle_large_type_2_50cdb6312bdbaf51a318b7379f4543ad.png?width=1200)
Trimeshとpyplotで点群ファイル(ply)を表示して点群を削減
昨日に引き続き点群ファイルのお勉強
google colabにおいたmesh.plyを表示したり加工したりしてみる
データ準備
google driveをマウント
from google.colab import drive
drive.mount('/content/drive')
![](https://assets.st-note.com/img/1724737754781-kacusM7ukX.png?width=1200)
Trimeshなどのライブラリをインストール
1. trimesh
概要: trimeshは、Pythonで3Dメッシュと点群データを操作するための強力なライブラリです。様々な3Dフォーマット(OBJ、PLY、STLなど)の読み書きが可能で、メッシュの解析、操作、レンダリングなどを行うための多機能なツールキットを提供しています。
主な機能:
メッシュの読み込み、保存
メッシュの法線計算、頂点、面の操作
メッシュの表示
3Dデータの処理(ブール演算、メッシュの簡略化、修復など)
用途: 3Dモデルを扱うアプリケーション、研究、3Dプリント、コンピュータビジョンなどで使用されます。
2. scipy
概要: scipyは、科学技術計算を行うためのPythonライブラリです。数値計算のためのnumpyを基盤にしており、特に線形代数、統計、信号処理、最適化などの幅広い数学的機能を提供します。
主な機能:
線形代数(行列演算、固有値問題など)
統計関数
信号処理(フィルタリング、フーリエ変換など)
最適化アルゴリズム
数値積分
用途: 科学技術計算、機械学習、データ分析、シミュレーションなど幅広い分野で使用されます。
3. pyglet
概要: pygletは、クロスプラットフォームなマルチメディアアプリケーション(特にゲームやグラフィックアプリケーション)を作成するためのPythonライブラリです。OpenGLを使って高速な2Dおよび3Dレンダリングを行うことができます。
主な機能:
2D/3Dグラフィックスのレンダリング
ウィンドウ管理(フルスクリーン/ウィンドウモードの切り替え)
キーボード、マウス、ゲームコントローラーの入力処理
マルチメディア再生(音声、動画)
用途: ゲーム開発、グラフィックスアプリケーション、マルチメディアアプリケーションの構築に使用されます。
!pip install trimesh scipy pyglet
PLYを表示
import trimesh
import matplotlib.pyplot as plt
# PLYファイルのパスを指定
file_path = '/content/drive/MyDrive/Colab_Notebooks/mesh.ply' # PLYファイルのパスを指定
# 点群データの読み込み
point_cloud = trimesh.load(file_path)
# 点群データの表示
fig = plt.figure(figsize=(10, 10))
ax = fig.add_subplot(111, projection='3d')
# 点群の座標を抽出してプロット
ax.scatter(point_cloud.vertices[:, 0],
point_cloud.vertices[:, 1],
point_cloud.vertices[:, 2],
s=0.1) # s=0.1 で点の大きさを設定
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
ax.set_title('3D Point Cloud')
plt.show()
![](https://assets.st-note.com/img/1724737950360-ZAnmX8cxEk.png?width=1200)
点群の数を取得
続いて色々試してみる
# 点の数を取得
num_points = len(point_cloud.vertices)
# 点の数を表示
print(f"点群の点の数: {num_points}")
結果
点群の点の数: 689176
![](https://assets.st-note.com/img/1724739501134-qlResT4pYO.png?width=1200)
点群を軽量化=サンプリング
サンプリング(点群の間引き)を行います。点群を軽くしてパフォーマンスの向上が可能です。
import numpy as np:
NumPyライブラリをnpという略称でインポートします。これにより、np.random.choiceなどのNumPyの関数を使用できるようになります。
サンプリングの実行:
np.random.choiceを使用して、点群データから指定された割合(例: 10%)の点をランダムにサンプリングします。他に均等間隔サンプリング、領域サンプリング、グリッドサンプリングがあるようです。
os.path.getsize
ファイルサイズを表示するためには、Pythonのos.path.getsize関数を使用します。この関数を使うことで、指定されたファイルのサイズをバイト単位で取得できます。取得したファイルサイズをわかりやすく表示するためには、バイトをキロバイト(KB)、メガバイト(MB)などに変換することもできます。
import os
import numpy as np
import matplotlib.pyplot as plt
import trimesh
# ファイルパスを設定(適宜変更してください)
file_path = '/content/drive/MyDrive/Colab_Notebooks/mesh.ply'
# ファイルが存在するか確認
if os.path.exists(file_path):
print(f"ファイルが見つかりました: {file_path}")
# ファイルサイズを取得して表示
file_size_bytes = os.path.getsize(file_path)
file_size_kb = file_size_bytes / 1024 # キロバイトに変換
file_size_mb = file_size_kb / 1024 # メガバイトに変換
print(f"ファイルサイズ: {file_size_bytes} バイト ({file_size_kb:.2f} KB, {file_size_mb:.2f} MB)")
else:
raise FileNotFoundError(f"ファイルが見つかりませんでした: {file_path}")
# 点群データの読み込み
point_cloud = trimesh.load(file_path)
# 点の数を取得(サンプリング前)
num_points = len(point_cloud.vertices)
print(f"元の点群の点の数: {num_points}")
# 点の座標を取得
x = point_cloud.vertices[:, 0]
y = point_cloud.vertices[:, 1]
z = point_cloud.vertices[:, 2]
# サンプリングして表示(例えば、全体の10%を表示)
sample_fraction = 0.1 # 表示する割合
sample_indices = np.random.choice(range(num_points), size=int(num_points * sample_fraction), replace=False)
x_sample = x[sample_indices]
y_sample = y[sample_indices]
z_sample = z[sample_indices]
# サンプリング後の点の数を表示
num_sampled_points = len(x_sample)
print(f"サンプリングされた点群の点の数: {num_sampled_points}")
# サンプルをプロット
fig = plt.figure(figsize=(10, 10))
ax = fig.add_subplot(111, projection='3d')
scatter = ax.scatter(x_sample, y_sample, z_sample, c=z_sample, cmap='Spectral', s=1)
fig.colorbar(scatter, ax=ax, label='Z value')
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
ax.set_title('Sampled Point Cloud Visualization')
plt.show()
結果
ファイルサイズも点群数も10%になりました。
ファイルが見つかりました: /content/drive/MyDrive/Colab_Notebooks/mesh.ply
ファイルサイズ: 21308341 バイト (20808.93 KB, 20.32 MB)
元の点群の点の数: 689176
サンプリングされた点群の点の数: 68917
![](https://assets.st-note.com/img/1724739468040-9sH8TErEc5.png?width=1200)
まとめ
plyファイルをTrimeshとpyplotで点群ファイル(ply)を表示して点群を削減できました。今回はランダムサンプリングを試しました。
次はゴミデータ点群を削除をしてみようかと思います。