🖼️

3D Gaussian Splattingのシーン作成・再生の環境構築

に公開

3次元空間の色々な視点からのシーン作成が実用化されてきていて、例えばバスケとかでダンクシュートを決めた瞬間に角度を変えた映像を映すなど、カメラで撮影してない角度からの画像を見せるようなことも増えてきています。NERF(Neural Radiance Fields)が代表的ですが、3D Gaussian Splatting (3DGS)が注目を集めています。

特にCVPR2025では、3DGSに関する論文が増えて来ているとのことで、注目度が高まってきているようです。私自身、1年前に3DGSをGoogle Colabで試してましたが、1年ぶりに試したところ動かせなくなっていたため、再度動画からシーン生成をするための環境を構築してみました。

3D Gaussian Splattingの基礎知識

フォトグラメトリとCOLMAP

フォトグラメトリは写真から3Dモデルを生成するもので、複数の画像から類似点を見つけ出し、3Dを生成する古くからある手法。Google mapなどで、色々な視点の画像が見られるのもこの技術を使っています。この後で使うCOLMAPもフォトグラメトリのツールの一つでスタンフォード大学とGoogle AIによって開発されたフリーソフトで、Windows/Mac/Linuxで使用ができます。

NERF (Neural Radiance Fields)

NERFは2020年に発表された深層学習を活用して2次元画像から3Dシーンを再構成できます。3Dシーンを生成する手法としては画像を使わずに、LiDARで直接3次元計測してから構成する手法もありますが、点群データは座標と色は持っていますが、違う角度から見たときの見た目の色の変化を表すことができません。NERFではある方向から対象物を見た時にどのような見え方をするかを予測することができます。

以下の図はNERFの論文からの抜粋で、SfM(Structure from Motion)で得られる空間座標のx,y,zと視点のθ,φの5つの入力から色と密度を計算します。密度は物体があるかという尺度に近く、この色と密度から実際の差分を計算して、ニューラルネットワークの重みを更新します。1つの3Dシーンを作るごとにこのプロセスが行われるので、他の深層学習のモデルのようにあるデータセットで学習モデルで別のデータを推論を行うのとは違う感じです。そのため、計算時間がどうしても掛かってしまうという欠点があります。一旦シーンを作成すると、任意のカメラの位置を指定すれば、そこの視点の画像を生成することができます。

3D Gaussian Splatting (3DGS)

3DGSは2023年に発表された手法です。こちらもシーン生成ごとに学習プロセスは必要ですが、シーン生成を少しでも高速化するために、ニューラルネットワークの代わりに3Dガウス分布を使ってレンダリングし、高解像度の画像を高速に生成できるようにしてます。以下の論文の図のように、SfMの点群データから3Dガウス分布を作成し、カメラの位置・視点の情報をもとにレンダリングした画像と元の画像が適合するように最適化し、画像を生成します。

LumaなどのiPhoneアプリでもすでに実装されていますが、ここでは自分でやってみる方法について共有しておきます。

3DGSの実行方法

以下では、私のmacbook air (M1)の環境から実行しています。
今回は今月九州出張して、マリンメッセ福岡に行き、不思議なオブジェを見つけたので、その動画を使うことにします。

入力データの作成

3DGSの入力データとして、点群データやカメラ位置・視点を作成する必要があります。COLMAPのMacbook airへは、このサイトの手順でインストールしました。

今回用意した画像は先週福岡マリンメッセに行った時に撮像した変なオブジェの動画から2フレームごとに切り出した画像を740枚用意しました。(10フレームごとに切り出した194枚だとかなり粗い結果になってしまいました)

まずCOLMAPで点群データを作成してみます。実際の使い方はこちらのサイトを参考にしてます。

気をつけないといけないのは、Feature extractionでPINHOLEを選択する必要があり、デフォルトのSIMPLE_RADIALを使用すると、後で3DGSのtraining時にAssertionErrorが発生してしまいました。作成した点群データは以下の図の結果で、exportとするとcameras.bin, images.bin, points3D.binが出力され、これが3DGSの入力となります。

以下のステップで作成してます。

  • Feature extraction
    • Shared for all imagesにチェックをいれる
    • first_octaveを"0"に変更する
  • Feature matchingは変更なし
  • Reconstruction options
    • multiple modelsのチェックを外す

最後にReconstructionの結果をExport allで出力します。そして以下のような構成にしておき、GDriveに置いておきます。(Google colabでGDriveからデータを読み込むため)

3DGSでのシーン生成

3DGSはGoogle colabを使用してます。Colab用notebookは一年前はこのgithubを使用していました。ただ、Google colabの環境が更新されたからか、うまく動かなくなっていて、Pythonのバージョンをダウングレードする必要があります。ちょうど対策が公開されていたので、こちらを使用してます。

COLMAPで生成したファイルを3DGSに入力します。メモリをかなり消費するらしく、ColabのGPUはL4を使用しました。Trainingで約1時間強、出力フォルダーにpoint_cloud.plyというファイルが生成されます。シーンの再生ではこのplyファイルが必要になります。

シーンの再生

結果を見るにはSIBRというものをベースとした可視化ツールが用意されていますが、私のmacbookではうまく動作できずに結局断念しました。BlenderやUnityでもやり方を探している中で、Unityが3DGSを読み込むためのAPIがこのサイトで紹介されていて、Unityで動かすことができます。

ただ、結構重いのと、Unityを使ったことがない人にはハードルが高いかもしれません。1年前はUnityを使っていたのですが、今はFreeのplyのビューワーがあったので、今回はそれを使います。(ただUploadしたデータの扱いなど、規約がないのでわからないため、取り扱いは注意した方がいいかもしれません。

以下が結果です。まずまずできているような気がします。

まとめ

まずまずの結果ですが、結構期待も多かったので、もう少し精度が上がったり、あとcolmapでのデータ生成や学習時間はやっぱり掛かりますね。

いいシーン再生をしようと思うと、動画の撮り方や、colmapでデータ生成する際のパラメータなどをもっと試行錯誤する必要がありそうです。3DGSを採用しているLuma AIも試してみたこともあるのですが、かなり注意深くiPhoneを動かさないといけないようで、きれいな3Dシーンの構築にはコツが必要そうでした。ただ、Luma AIが数分で3Dシーン構築ができることを考えると、色々と最適化したり、パワフルなGPUを使っているんだと思われ、そう考えるといいアプリだなと改めて思います。

色々と3DGSの改善版が出ているので、これから試していこうと思います。

Discussion