概要
本ワークフローは全天球画像:Equirectangular(正距円筒図法)画像を使って、ロバストかつ比較的高速にカメラアラインメント(SfM)を行い、3D Gaussian Splatting(3DGS)の学習を行うワークフロー例を示します
参考
DJI AVATA360での撮影例
- https://x.com/kotohibi_3d/status/2079907663895482456
- https://x.com/kotohibi_3d/status/2040724840504758578
- https://x.com/naribubu/status/2038881884558791088
- https://x.com/naribubu/status/2038875398717722743
DJI OSMO360での撮影例
- https://x.com/kotohibi_3d/status/2088521899160879450
- https://x.com/kotohibi_3d/status/2082426800215654725
- https://x.com/kotohibi_3d/status/2074821581948481758
- https://x.com/kotohibi_3d/status/2038179454367957106
必要な物
-
360° カメラ
- DJI OSMO360
- DJI AVATA360
- Insta360
-
ハイエンドPCとNVIDIA GPU
- 3DGSの学習には高性能なGPUが必要になります。特にVRAMは多い方が良いです。最低でも12GB以上のVRAMを搭載したGPUを推奨します。
-
Metashape Standard (Professional版は未サポート)
- 全天球画像を直接SfM可能で、非常に高速&ロバストです
- https://www.agisoft.com/features/standard-edition/
-
3D Gaussian Splatting software
- Postshot: https://www.jawset.com/
- LichtFeld Studio(LFS): https://github.com/MrNeRF/LichtFeld-Studio
- Brush: https://github.com/ArthurBrussee/brush
-
動画から静止画切り出しツール
- Extract Sharpest Frame(無料版)
- 360 Extractor(有料版)
-
Metashape 360 SfMからCOLMAP形式のCubemap変換ツール
- Metashape 360 to COLMAP Converter(無料版)
- 360 MCConverter(有料版)
-
(任意) 3DCGの実寸を推定するための追加ライセンス
- Metashape 360 to COLMAP ConverterはAprilTagという二次元マーカーを利用して、3DGSの実寸を推定する機能があります。利用には追加ライセンスが必要です。AprilTagの利用方法は以下の記事で説明しています
- Add-on Real Scale 3DGS with AprilTag
- 英語版 : https://x.gd/CoWJA
- 日本語版 : https://x.gd/Isahb
動画撮影する(e.g. OSMO360)
カメラを自撮り棒に付けて、キャプチャしたい範囲をゆっくりと歩きます
動画設定はD-Log M, 30fps以上の撮影がお勧めです
動画を現像する
DJI Studioに撮影データを取り込み、現像処理(色復元)をします
- 下記画像の赤枠の設定を実施。
- (高度な設定)Extract Sharpest Frame V1.0.0から実装されたシームマスクを利用する場合、RockSteadyをoffにします。RockSteadyは電子手振れ補正、水平維持をする機能ですが、ステッチラインが変化します。Insta360の場合もそれに相当する機能はオフにします。
- (補足)シームマスクは前後の魚眼カメラのステッチラインのズレにマスクをして、後述のカメラアラインメントおよび3DGS学習から当該部分を除外することが可能です。
動画を書き出す
- 全天球動画としてMP4ファイルで動画を書き出します。設定例を下図に示します
- 複数クリップを現像する場合は"複数クリップ"で現像してもOKです。Extract Sharpest Frameは複数動画をバッチ処理できます。
動画から静止画を切り出す
- 動画から静止画を切り出す方法は様々あります。お好きな方法を調査、選択してください
ここでは私が公開しているツールをご紹介します
Extract Sharpest Frameは指定フレーム間隔で一番シャープな画像を切り出すツールです -
新機能はBOOTH版を優先的にupdateしております
| 主要項目 | 説明 |
|---|---|
| Video file | 全天球動画を選択。複数動画を選択し一括処理可能です。 注)マルチバイト文字を含むファイルパスは未サポート |
| Output folder | 静止画とマスクを切り出す先のフォルダを指定。このフォルダ以下にframesとmasksフォルダが作られます。複数動画から切り出した画像を一つのフォルダにまとめるかを選択可能です 注)マルチバイト文字を含むファイルパスは未サポート |
| Scale width | 全動画フレームの画像のシャープさを計算する時の画サイズです。大きくした方が緻密に計算されます。注)切り出し画像は常にオリジナル動画と同じ画サイズで切り出されます |
| Chunk size | 静止画を切り出す間隔を指定。30fps動画で30を指定すると1秒間隔で切り出されます |
| Workers | 画像のシャープさを計算する時のプロセス数を指定。4前後がお勧めです |
| Start(HH:MM:SS) | 切り出しを開始する時間を指定します。形式はHH:MM:SSです 空の場合は動画の先頭から開始します |
| End(HH:MM:SS) | 切り出しを終了する時間を指定します。形式はHH:MM:SSです 空の場合は動画の末尾まで処理します |
| Remove similar frames | 類似フレームを除外します。ReviewをONにすると実行時に閾値調整して切り出し枚数を調整可能です |
| pHash threshold | 類似画像の判定閾値を指定します。値が大きいほど画像を間引きます。撮影時の移動速度が不規則な場合に有効な機能です |
| Mask Generation | 人や自動車等のマスク画像を生成します。後段のSfMの精度が上がります |
| SAM3 Dual Mask | 最新版はSAM3マスク対応済みです。任意の短いセンテンスでマスク可能です。Preview/Editボタンでマスク結果を確認できます。 https://x.com/kotohibi_3d/status/2061044432837972367(高度な設定)SAM3は二通りのマスクを設定することが可能です。カメラアラインメントと3DGS学習用のマスクを分けることが可能です。詳細は次のGoogle Slideを参照してください https://t.co/X0uRH959RV |
| YOLO Mask | [YOLO Class IDs] 検出したいクラスIDを指定します。 0: person, 1: bicycle, 2: car, etc.カンマ区切りで複数ID指定可能です。https://github.com/ultralytics/ultralytics/blob/main/ultralytics/cfg/datasets/coco.yaml [YOLO Confidence] 閾値を上げると誤検知を減らせます。下げるとより多くを検出しますが誤検知は増えます [YOLO Model] yolo11nからyolo11x方向にモデルサイズが大きくなり高性能になりますが処理負荷は大きくなります
|
| Seam Mask | 2つの魚眼画像を繋げたステッチラインのズレにマスクをかける機能です。ステッチライン位置を固定するため、DJI Studio or Insta360 Studio等の水平維持機能をオフにして現像して本機能をご利用ください
|
| Custom Mask | 固定のマスク画像を指定します。上記マスクと併用する場合は融合されます。カメラリグ等が常に映り込む部分をマスクするのに有効です。 注)動画と同じ解像度のPNG画像を指定してください
|
| Analysis only | 画像のシャープさの計算のみ行います。出力フォルダに計算結果(メタ情報)が保存されます。次回から出力フォルダにメタ情報があると、解析フェーズをスキップして画像切り出しができます。Chunk sizeを調整した場合に有効です。 |
| Save config | 上記の設定を設定ファイルとして保存します |
| Load config | 保存した設定ファイルを読み込みます |
| Run | 処理実行 |
実行結果
カメラアラインメント(SfM)をする
SfMは全天球画像をダイレクトに処理できるMetashape Standardを使います
切り出した全天球画像をロードします
Camera TypeをSphericalに変更
マスク画像の読み込み
SfMのパラメータ設定
- [Workflow]->[Align Photos]
私が良く使うパラメータ2例を示します
実行
Tie pointsのクリーンアップ
- 信頼性の低いTie pointsを削除して、SfMの精度を上げます
これは高精細な3DGSにおいてとても重要な作業になります
[Tools]->[Tie Points]->[Clean Tie points]を選択します
- [Reprojection error]を選択してスライダーを調整して5%程度のTie pointsを削除するのがお勧めです
- 画面左下にTie points数が表示されるので、削除対象のTie points数を確認しながらスライダーを調整してください
- [Optimize Cameras]を押して、カメラの最適化を行います
- [Recosntruction uncertainty]も同様に5%程度のTie pointsを削除して、再度[Optimize Cameras]を行います
- [Projection accuracy]も同様に5%程度のTie pointsを削除して、再度[Optimize Cameras]を行います
- 上記をもう一度繰り返して、最終的に信頼性の低いTie pointsが削除されている状態にします
SfM結果のエクスポート
- Camera情報のエクスポート
[File]->[Export]->[Export Cameras]でAgisoft XML(*.xml)を選択して保存します - Point Cloudのエクスポート
[File]->[Export]->[Export Point Cloud]でStanford PLY(*.ply) を選択して保存します
COLMAP Cubemapに変換する
- MetashapeのSfM結果からCOLMAP形式の6方向画像のCubemapに展開します
ここでは私が公開しているツールをご紹介します
Metashape 360 to COLMAP Converter - 新機能はBOOTH版を優先的にupdateしております
設定①
| 主要項目 | 説明 |
|---|---|
| Input Images Folder | 切り出した全天球画像フォルダを指定 注)マルチバイト文字を含むファイルパスは未サポート |
| Metashape XML | SfM結果のCamera.xmlを指定 注)マルチバイト文字を含むファイルパスは未サポート |
| PLY File | SfM結果のpoint_cloud.plyを指定 注)マルチバイト文字を含むファイルパスは未サポート |
| Output Folder | Cubemap展開先のフォルダを指定 注)マルチバイト文字を含むファイルパスは未サポート |
| Crop Size | 6方向に切り出す画サイズ、OSMO360の8K動画の場合は1920でOK |
| FoV | 6方向に切り出す視野角、90°でOK |
| Max Images | 全天球画像の処理枚数上限、動作テストする際に小さい値を指定してください |
| Image Range | 処理対象の全天球画像を範囲指定可能、部分的に処理する際に指定ください |
| Workers | 処理のプロセス数、お使いのCPUのコア数に応じて増減させてください |
| Yaw Offset | CubemapのYaw角度にバリエーションを持たせることが可能。Cubemap毎に指定角度が加算されます。5~30°の範囲がお勧めです |
| Save Config | 上記設定値を設定ファイルとして保存可能 |
| Run Conversion | Cubemap変換処理を開始 |
設定② マスク処理
- ※Extract Sharpest Frameで生成したSAM3マスクを利用する場合は本機能はオフにしてください。下記カスタムマスクにSAM3マスクを指定してください
- 人物や自動車等のマスクを生成することが可能です
特に360 Cameraは自身が映り込む為、マスク生成は重要な作業になります
| 主要項目 | 説明 |
|---|---|
| Mask Pass Mode | Singleは全天球画像でオブジェクト認識します。高速ですが精度は低いです。Dualは全天球画像とCubemap画像両方でオブジェクト認識します。処理量は多いですが、認識精度が高いです |
| Merge Mode | Dualモード時にマスクを結合させるモードです。unionは双方の単純結合、refineはCubemapのマスクをベースに全天球マスクが統合されます。refineがお勧めです |
| YOLO Class IDs | 検出したいクラスIDを指定します。 0: person, 1: bicycle, 2: car, etc. カンマ区切りで複数ID指定可能ですhttps://github.com/ultralytics/ultralytics/blob/main/ultralytics/cfg/datasets/coco.yaml |
| YOLO Confidence | 閾値を下げると認識率は上がりますが、ノイズも増えます |
| Enable overexposure mask | 白飛び画素は3DGS学習時にノイズ成分になる場合があります、除去したい場合に有効にしてください |
設定③(高度な設定)カスタムマスク
- Extract Sharpest Frameで生成したSAM3 Dual Mask(3DGS学習用)またはカスタムマスクをロード可能です。マスク画像は静止画と同じ枚数、同じ解像度のPNG画像、同じファイル名で指定してください。
参考:Google Slide -> https://t.co/X0uRH959RV
設定④(高度な設定)AprilTag
- 二次元マーカーを利用して、3DGSの実寸を推定する機能です。利用には追加ライセンスが必要です。AprilTagの利用方法は以下の記事で説明しています。
- 英語版 : https://x.gd/CoWJA
- 日本語版 : https://x.gd/Isahb
設定⑤(高度な設定)Overlapフィルタ
- [JP]全天球動画と平面画像の混合3DGSワークフローを参照してください
- BOOTHからダウンロードしたzipに詳細な操作説明書(PDF)が含まれています。それを参照してください
- 参考:https://x.com/kotohibi_3d/status/2078088377371681237
設定⑥(高度な設定)Cubemap削減
- 3DGSの品質低下を最小限に抑え、Cubemapを削減する機能です。3DGS学習時間の短縮、VRAM使用量の削減を期待できます
- BOOTHからダウンロードしたzipに詳細な操作説明書(PDF)が含まれています。参照してください
- 参考:https://x.com/kotohibi_3d/status/2086408535768973659
実行
(Postshot編)3D Gaussian Splattingの学習
ここではPostshotを使って説明します
Cubemapの取り込み
Mask設定
Cubemapの取り込み結果
3DGS学習開始
- 私が広域3DGSで使う学習パラメータ例を示します。シーンに合わせてパラメータは調整してください
- Photometric Compensationをオンにします
- Max Splat Countをシーンの大きさに応じて変更します(3,000~12,000kSplats)
- Max Sph.Hrm.Degreeを調整します(1~3), VRAMが少ない環境は1を推奨します
- Stop Training Afterは画像枚数によって自動計算されます
3DGS学習結果
(LichtFeld Studio編)3D Gaussian Splattingの学習
ここではLichtFeld Studio(LFS)を使って説明します
Cubemapの取り込み
3DGS学習開始
- Mask設定
- [Training Parameters]->[Mask Mode]->[Ignore]を選択します
- [Alpha Mask]はオフにします
- 学習パラメータ
- 私が良く使う設定を下図に示します
- [Strategy]->[MRNF]をお勧めします(※この記事執筆時点)
- Max Gaussiansをシーンの大きさに応じて変更します(3,000,000~12,000,000)
- SH Degreeを調整します(1~3), VRAMが少ない環境は1を推奨します
- IterationsとSteps Scalerは画像枚数に応じて自動計算されます
- MRNFの場合、その他のパラメータの変更はあまり必要ありません
- LFSはパラメーターが多いためWebで調べてシーンに最適な設定を探してください
- ※最近はBilateral Gridはオフにする場合が多いです。(PPISPで十分な場合が多い)
- [Start Training]を押して3DGSの学習を開始します。
3DGS学習結果
最後に
3DGSの手法は様々で、本記事は一例に過ぎません。最新の情報は私のXで発信していきます
是非ご自身でも調査してより良い手法を開発してください。Enjoy 3DGS :)
- my X: https://x.com/kotohibi_3d
- 3DGS pipeline guide: https://github.com/Kotohibi/3DGS_pipeline_guide






















