記事検索

検索ワードを入力してください。
Sky Tech Blog
Streamlitで​3D点群を​表示する

Streamlitで​3D点群を​表示する

Streamlitを用いてWeb上で3D点群データ(PLY)を表示する方法を紹介。インタラクティブな操作が可能で、簡単に実装できます。3D点群データを扱う方におすすめの内容です。

Streamlitを用いて、Web上で3D点群データ(PLY)表示を行ってみたのでご紹介します。

点群を表示し拡大縮小・回転・移動などインタラクティブに操作することができます。
データが大きすぎると重くなってしまうこともありますが、簡単に表示して見る用途には適していると思います。

3D点群データを扱われている方はぜひ参考にしてみてください!

Streamlitとは

Streamlitは、PythonでWebアプリケーションを作成するためのフレームワークです。
Pythonのコードを数行書くだけで、気軽にデモ用のアプリを作成することができます。GUIなどもPythonの簡単なコードのみで実装できます。

pydeckとは

pydeckは、Pythonでdeck.glによる空間レンダリングを行うためのライブラリです。
deck.glとは地図上にデータを描画するためのフレームワークであり、WebGLベースのため、高速に大量なデータが表示可能となります。

開発環境・セットアップ

◎ 開発環境

  • VSCode
  • Python 3.8.10

⚠️ Python 3.11以降はOpen3Dが対応しないのでバージョンに注意

◎ セットアップ

仮想環境venv上での環境構築を実施

python3 -m venv (任意の仮想環境名)
source (任意の仮想環境名)/bin/activate
(任意の仮想環境名) python -m pip install --upgrade pip
(任意の仮想環境名) python -m pip install streamlit
(任意の仮想環境名) python -m pip install open3d
(任意の仮想環境名) streamlit run ply_viewer.py

実装

点群データの絶対パスを入力するとその点群が表示されるWebアプリを作成しました。
以下に、操作ごとに分割したソースコードを掲載します。(アプリ全体のソースコードは次項に掲載しています。)

  • Open3Dで点群を読み込みデータフレームを作成
# Open3Dで点群を読み込み
pcd = o3d.io.read_point_cloud(ply_path)

# サンプルデータの各点の値が小さかったため1000をかけて表示
points = np.array(pcd.points) * 1000
df_points = pd.DataFrame(points, columns=['x', 'y', 'z'])
colors = np.array(pcd.colors) * 255
df_colors = pd.DataFrame(colors, columns=['r', 'g', 'b'])
df = pd.concat([df_points, df_colors], axis=1)

コメントでもあるように、今回使用したサンプルデータの各点の値が小さすぎたため、1000をかけることで拡大しています。
1000をかける処理は使用するデータによっては不要です。

  • pydeckで表示させる点群のレイヤーを作成
point_cloud_layer = pydeck.Layer(
    "PointCloudLayer",
    data=df,
    get_position=['x', 'y', 'z'],
    get_color=['r', 'g', 'b'],
    get_normal=[0, 0, 15],
    auto_highlight=True,
    pickable=True,
    point_size=1
)
  • 表示画面の状態を調整
# 表示の初期状態を調整するために中心位置を取得
target = [df.x.mean(), df.y.mean(), df.z.mean()]

# データに応じて画面の状態を調整
view_state = pydeck.ViewState(target=target, controller=True, rotation_x=15, rotation_orbit=50, zoom=1.5)
view = pydeck.View(type='OrbitView', controller=True)

中心位置を合わせていても、ズームしすぎていると点群がフレームアウトして画面上に映らないこともありました。
うまく表示されない際にはこの辺りを調整すると良いと思います。

  • htmlで画面上に表示
obj = pydeck.Deck(point_cloud_layer, initial_view_state=view_state, views=[view])
# htmlで画面上に表示
components.html(obj.to_html(as_string=True), height=600)

ソースコード全体

点群データの絶対パスを入力するとその点群が表示されるWebアプリの全体の実装は以下のようになっています。

# Streamlitで3D点群表示
import streamlit as st
import os
import open3d as o3d
import numpy as np
import pandas as pd
import pydeck
import streamlit.components.v1 as components

st.set_page_config(layout="wide")

st.title("Streamlitで点群表示")

# pathを読み込み
ply_path = st.text_input('PLYデータの絶対パスを入力')

if os.path.exists(ply_path):
    # open3dで点群を読み込み
    pcd = o3d.io.read_point_cloud(ply_path)
    # サンプルデータの各点の値が小さかったため1000をかけて表示
    points = np.array(pcd.points) * 1000
    df_points = pd.DataFrame(points, columns=['x', 'y', 'z'])
    colors = np.array(pcd.colors) * 255
    df_colors = pd.DataFrame(colors, columns=['r', 'g', 'b'])
    df = pd.concat([df_points, df_colors], axis=1)

    # 点群を表示するレイヤーを作成
    point_cloud_layer = pydeck.Layer(
        "PointCloudLayer",
        data=df,
        get_position=['x','y','z'],
        get_color=['r', 'g', 'b'],
        get_normal=[0, 0, 15],
        auto_highlight=True,
        pickable=True,
        point_size=1
    )

    # 表示の初期状態を調整するために中心位置を取得
    target = [df.x.mean(), df.y.mean(), df.z.mean()]

    # データに応じて画面の状態を調整
    view_state = pydeck.ViewState(target=target, controller=True, rotation_x=15, rotation_orbit=50, zoom=1.5)
    view = pydeck.View(type='OrbitView', controller=True)

    obj = pydeck.Deck(point_cloud_layer, initial_view_state=view_state, views=[view])

    # htmlで画面上に表示
    components.html(obj.to_html(as_string=True), height=600)

else:
    st.write("データが見つかりません")

結果

都合上結果はお見せできませんが、上記ソースコードを実行し点群データのパスを入力すると、点群データが表示され、移動・回転・拡大・縮小することができます。
色情報を含む点群の表示も可能です。各点のRGBデータが入っていれば、点ごとに色がついて表示されます。

おわりに

簡単ではありますが、Streamlitを用いてWeb上で3D点群データ(PLY)を表示する方法についてご紹介しました。
少ない実装量でお試しできるので、3D点群データを扱っている方や、記事を読んで興味を持ってくださった方はぜひお試ししてみてください。

最後までお読みいただき、ありがとうございました。


XFacebookLINE
Sky株式会社のソフトウェア開発や製品、採用に関するお問い合わせについては、下記のリンクをご確認ください。
お問い合わせ
ホーム