40
19

さまざまなNeRF・3DGSを検証してみた!! powerd by デジタル・フロンティア

Last updated at Posted at 2024-06-05

自己紹介

名城大学理工学研究科メカトロニクス工学専攻修士2年のAsterです。
現在デジタルフロンティア様にて、NeRF・3DGS検証業務を行っています。検証の目的は、将来的に実写映像作品にNeRF・3DGSを活用できないか検討することで、今回の検証はそのための第一歩となります。
2023年5月から一年間行ってきたNeRF・3DGS検証に関して記事にしました。
ぜひ見てくだされば嬉しいです。


※本記事に記載されている情報は、著者および関係者の知識と経験に基づいて提供されているものであり、正確性や完全性を保証するものではありません。記事の内容に基づくいかなる行動も、読者自身の責任で行ってください。また、技術や規格は常に進化しており、この記事の情報は執筆時点のものであることをご了承ください。最新の情報を確認するためには、公式ドキュメントや信頼できる情報源を参照することをお勧めします。

NeRFとは

Neural Radiance Fields(NeRF)は2020年にコンピュータビジョンのトップカンファレンスの一つであるECCVで採択され、Best Paper Honorable Mentionにも選出されました。Best Paper Honorable Mentionは採択された論文の中でも特に優れたものとして、Best Paperに次ぐ賞となっています。このNeRFは世に出た2020年以来、わずか3年で4000本近く引用されている非常に優れた最先端技術の一つとなっています。

NeRFは、多数の画像から任意の視点から見た画像を推測する「自由視点画像生成」の技術の一種です。多数の画像から、三次元位置をある方向から見たときの色と密度を表現するRadiance Fieldsというデータ(関数)をニューラルネットワークによって学習します。このRadiance Fieldsを使って、新しい位置から見た画像を作ることができます。

自由視点画像を生成するまでの流れ

画像を入力としてNeRFによる新たな角度からの画像を作る手順は次のとおりです。

  1. 物体を色々な方向から撮影する(Input Images)
  2. 画像からカメラ位置姿勢を推定する(Structure from Motion : SfM)
  3. 画像とカメラ位置姿勢からRadiance Fieldsを学習する (Optimize NeRF)
  4. 学習したRadiance Fieldsから新たなカメラ位置から見た画像を作る (Render new views)

このうち、厳密にNeRFの技術としては、3. 4. の部分のみを指します。2の部分に関してはStructure from Motion(SfM)という技術であるため注意しましょう。
SfMはCOLMAPなどソフトウェアを使用してカメラ位置姿勢を推定することが多いです。
NeRFは位置・方向を入力としているため、1つのカメラが間違った位置にあると、すべてのレンダリングが失敗する可能性があります。つまり、カメラの位置と向きがどのように計算されるかも理解しておくことでどういう画像が必要なのかわかるため、非常に重要です。

位置・方向の推定について

Colmap の心臓部は SIFT (Scale Invariant Feature Transform)と呼ばれる特徴検出アルゴリズムが使用されてます。
次のように複数の写真で同じ点の特徴を検出します。
knn.PNG

対照的な境界線,角,または先端を持つ画像が必要で、空の雲,白い壁,光沢のある反射素材などの特徴に関しては位置推定が難しいです。
入力画像の注意点

  • 視差を意識する
  • 遠近感をつける
  • 撮影枚数を多くする

NeRFの学習の流れ

NeRFの学習の流れは次のとおりです。

  1. COLMAPにより推定した様々なカメラ座標を取得
  2. 上記のカメラ座標と、それに伴う視線方向をニューラルネットワークへの入力とし、色と体積密度の情報を推定
  3. 色と体積密度の情報をボリュームレンダリング技術を使って2D画像に変換
  4. 変換した2D画像と正解画像との2乗誤差を求める
  5. 誤差逆伝搬法を用いてニューラルネットワークの重みを更新

この流れによって自由視点画像を生成することが可能となっています。
より詳しく説明していきます。
NeRFは,与えられた画像集合から、モデルFθを構築することが目標です。

スクリーンショット 2024-06-03 13.56.12.png

このFθである視点(青丸)から見た時の位置(赤丸)が何色かをニューラルネットワークF(θ)を使用して推定する学習モデルです。
スクリーンショット 2024-06-03 13.59.06.png

以下のように色を推定します。

image.png

この流れを入力画像のレイ方向の全座標・全てのピクセルで行います。
推定した色と密度の情報を使ってボリュームレンダリングを行い、画像を生成します。

生成した画像と正解画像での2乗誤差を求め,誤差逆伝播法を用いてニューラルネットワークF(θ)の重みを更新していきます.
スクリーンショット 2024-06-03 14.02.36.png

この流れを行い,ニューラルネットワークF(θ)を最適化することで,自由視点画像を生成することができます.

3DGSとは

3D Gaussian Splatting(3DGS)は、INRIAがSIGGRAPH 2023で提案した方法です。カメラのポーズを提供する2D画像上に「スプラット」(投影)され、ピクセルごとの色を得るためにラスタライズされます。ラスタライゼーションはGPU上で非常に高速であるため、この方法はNeRFよりもはるかに高速にレンダリングできます。簡単に言うと点群を楕円形にして表現している感じです。
レンダリング時は機械学習を不要なため、リアルタイムにレンダリングが可能です。
昨今ではLuma AIの登場もあり、スマホで動画を撮影するだけで手軽に3D Gaussian Splatting技術を用いた空間の3D化を行うことができるようになりました。

3DGSがどんなものかざっくりイメージを知っていただくために流れ沿って説明していきます。
理論的な内容を詳しく知りたい方はこちらの記事がお勧めです。

flow.PNG

3DGSは次の流れで生成されます。

  1. カメラ位置姿勢推定・疎点群の推定
  2. ガウシアンのパラメータ最適化
  3. パラメータ最適化における適応的制御
  4. ガウシアン用の高速微分可能ラスタライザ

NeRFについて説明する際に自由視点画像を生成するまでの流れで記載した、カメラ位置姿勢の推定まではほとんど一緒で、ガウシアンパラメータの最適化以降が異なります。

パラメータ最適化における適応的制御で行っていることは次のとおりです。
黒いラインがGeometryで、緑がgaussian 集合とします。
再構成が不十分な領域のある小さなgaussianに関しては、同じ大きさのgaussianをコピーし、それを位置勾配の方向に移動させます。
分散の大きい領域の大きなgaussianに関しては、小さなgaussianに分割する必要があります。その場合、2つのgaussianで置き換え、それらのスケールを実験的に求めた係数p = 1.6で分割します。
ワールド空間で非常に大きいガウシアンやビュー空間で大きなフットプリントを持つガウシアンを定期的に除去します。
Gaussian.PNG

このように、ガウシアンのパラメータを最適化していき、画像を生成し、最終的に入力のカメラから見たときの画像と推論したときの画像が近くなるように学習をしていきます。

NeRFと3DGSの比較

NeRFと3DGSの比較に関して使用するのはNerfstudioのモデルであるnerfactoとsplatfactoを用いてます。
まず学習時間に関してです。
nerfactoは、学習時間が50分
splatfactoは、学習時間が31分で学習時間が短くなっている。
また、レンダリングもsplatfactoのほうが早い。

次に品質に関してです。
品質に関しては、nerfactoよりもsplatfactoのほうが高品質です。
次の画像は上がnerfactoで、下がsplatfactoです。

細かい箇所をFocusするとよりわかりやすい。
次の画像は上がnerfactoで、下がsplatfactoです。

nerfacto-detail.PNG

splatfacto-detail.PNG

さまざまな3DGSでの比較について

今回検証で使ったモデルは以下のとおりです。

この検証結果から、Mip-Splattng、Nerfstudio(Splatfact)、Postshotが高品質です。

高品質な動画を出力するまでの流れ

動画を出力するまでの流れは以下のやり方が検証した中で綺麗なやり方であると考えています。

  1. 撮影
  2. Nerfstudio(Splatfacto)で学習
  3. SuperSplat・PostShotにてノイズ除去
  4. PostShotでAfter Effectsに渡せるファイルへ変換
  5. After Effects にて可視化
  6. 動画出力

この流れで出力した動画が次の動画になります。

今回Nerfstudioでの学習にした理由として、

  • 高品質な3DGSを生成できること
  • Nerfstudioはパラメータ調整が細かく設定でき、商用利用が可能であること
  • PostShotの学習結果は綺麗であるが、2024/05/29時点でBeta版で商用利用が不明であること
  • オリジナルの3DGSやMip-Splattingは商用利用が不可であること
    などを踏まえて、Nerfstudioでの学習にしました。

今回この流れに沿って説明していきます。

撮影方法について

NeRFや3DGSを行う上で、写真や動画で撮影することがありますが、今回は写真での撮影のみを記載します。

撮影をするうえで注意するべき点は次のとおりです。

  • 静止体
  • 露出が一定である
  • さまざまな角度と視点
  • 特徴点の多さ
  • ぶれがないか
  • 撮影距離
  • 画像枚数

上の項目に関しては,次の動画にて説明しているので,そちらをご覧ください.

実際に直線での撮影に関して説明していきます.

まず,直線の場合は次の赤線に沿って撮影していきます.
この時撮影する間隔は,1.5-2歩間隔で撮影するのがおすすめです.

スクリーンショット 2024-06-03 12.57.14.png

まず,進む方向に平行に撮影をしていきます.

スクリーンショット 2024-06-03 13.01.20.png

次に,カメラを斜め方向に向けて,撮影を行います.
スクリーンショット 2024-06-03 13.03.24.png
スクリーンショット 2024-06-03 13.03.42.png

これを逆方向からも撮影します.

次に,建物に平行に撮影も行います.
スクリーンショット 2024-06-03 13.11.00.png

もし,高いビルなどを撮影する場合は,1脚を用いて,高い視点からも撮影しましょう.
1脚がない場合は,次の画像のようにカメラを上に向けつつ撮影するといいです.

スクリーンショット 2024-06-03 13.10.39.png

このように直線の場合は,このように撮影を行うと高品質な3D Captureができます.

Nerfstudioでの3DGS学習方法

Nerfstudioについて

Nerfstudioは、2022年10月にカリフォルニア大学のバークレー校が開発したオープンソースです。
Nerfstudioは、NeRFの学習、レンダリングを簡単に行うことができます。
githubからコードを落としてきて、自身のPCに環境を構築する方法とGoogle Colabを使用する方法がありますが、今回は、自身のPCに環境を構築する方法について記載します。

Nerfstudioでの環境構築の方法

実行環境

Nerfstudioでは、NvidiaのGPUを使用するためにCUDA環境を用います。
また、Pythonのバージョンの環境はConda環境を使用します。
CUDAのバージョンは11.7もしくは11.8を使用します。
Pythonのバージョンは3.8.16を使用します。
pytorchのバージョンは2.0.1を使用します。

Windowsの方は,Visual Studio 2022をインストールをインストールしておきましょう.
これはCUDAをインストールする前に行う必要があります。
必要なコンポーネントはDesktop Development with C++ワークフロー(BuildTools版ではC++ Build Toolsとも呼ばれる)に含まれています。

Conda環境を作成

まず、Conda環境を作成します。
Condaとは、Pythonパッケージの依存関係を管理し、簡単に異なるプロジェクトや作業環境を区切って管理できる方法です。
Condaは、AnacondaやMinicondaをインストールすることで使用できます。
Anacondaは、数百の科学計算やデータ分析に関連するパッケージがあらかじめインストールされており、インストール後すぐに多くの作業が可能です。
そのため、手間のかかるインストール作業や細かな設定などの環境構築にかかる時間を短縮し、よく使うライブラリをまとめてインストールできます。
Minicondaは、要最小限のライブラリだけが入っていて、自分で必要なライブラリを追加していく軽量版で、自由にカスタマイズできます。
Nerfstudioを使用するには、Pythonのバージョンは3.8以上でなければいけません。

Conda環境のセットアップ方法は以下のとおりです.

これで、Nerfstudioの環境のベースとなるPython環境を作れます。

conda create --name nerfstudio -y python=3.8
conda activate nerfstudio
python -m pip install --upgrade pip
  • 必要なライブラリのインストール
    必要なライブラリとして、pytorch, Tiny-cuda-nnなどが必要です。
# pytorchのインストール
# CUDA11.7の場合のpytorchのインストール
pip install torch==2.0.1+cu117 torchvision==0.15.2+cu117 //
--extra-index-url https://download.pytorch.org/whl/cu117

# CUDA11.8の場合のpytorchのインストール
pip install torch==2.0.1+cu118 torchvision==0.15.2+cu118 //
--extra-index-url https://download.pytorch.org/whl/cu118
# tiny-cuda-nnのインストール
pip install ninja //
git+https://github.com/NVlabs/tiny-cuda-nn/#subdirectory=bindings/torch
# Pipを使用する場合のnerfstudioのインストール
git clone git@github.com:nerfstudio-project/nerfstudio.git
cd nerfstudio
pip install nerfstudio
# githubに上がっているコードからインストールする場合のnerfstudioのインストール
git clone git@github.com:nerfstudio-project/nerfstudio.git
cd nerfstudio
pip install --upgrade pip setuptools
pip install -e .

これでNerfstudioの環境を作ることができました。

Nerfstudioで学習

次にNerfstudioで学習してみましょう。
NeRF・3DGSの学習を行う場合の流れは、次の通りです。

  • 画像・動画データを用意する
  • 画像からカメラ位置姿勢を推定する
  • NeRF・3DGSの学習を行う

「撮影方法について」で説明したように撮影を行い、複数の写真を用意しましょう。
用意した写真は、次のディレクトリに画像データを入れましょう。

{Your Deirectory}\nerfstudio\data\nerfstudio

次にこの画像データのカメラ位置姿勢を推定します.

//カメラ位置姿勢の推定
ns-process-data images --data data/nerfstudio/polt/images //
--output-dir data/nerfstudio/polt/colmap

次にモデルを学習します.

//モデルの学習
ns-train splatfacto --data data/nerfstudio/polt/colmap

高品質な作品を作る場合はsplatfacto-bigを用いる。
コマンドを次のように変更すると使用できる。
他の学習モデルを使用したいときは以下の{model}の部分を変えましょう

//modelの変更
ns-train {model} --data data/nerfstudio/polt/colmap

コマンドを使用すると次のような画面になったら成功です。

NerfstudioのViewerについて

注意 : 2024/04/15時点でのViewerの使い方になります.NerfstudioのVersionによってViewerの使い方が変わる可能性があります.

今回は、Nerfstudioで学習結果をViewerで確認する方法のみ記載します。

NerfstudioでViewerにて見る方法は,以下のコマンドでviewerを立ち上げることができます.

ns-viewer --load-config {yourDirectory}/config.yml

上記のように動いたら,webブラウザ上で以下のブラウザを立ち上げます.

http://localhost:7007/

すると,以下のような画面が立ち上がります.

以下の赤枠のカメラフレームは,入力データの画像の位置を表しています.

このカメラフレームの表示・非表示は,以下の赤枠のボタンを押すことで切り替えることができます.

次にViewer上の解像度の変更についてです.
以下の赤枠のMax res のスライダーを変更することで,Viewer上の解像度を変更することができます.

以下の画像は2064px × 1144pxのViewerになります.解像度が変わったのがわかります.

Viewerで学習結果を見て、高品質な3DGSであれば、次のようにPLYファイルとして、出力しましょう。
PLYファイルとして出力する理由として、次の3DGSの編集で必要だからです。
exports/splatフォルダの中にPlyファイルが生成されます。

ns-export gaussian-splat --load-config {your config} --output-dir exports/splat

3DGSの編集について

3DGSを編集する方法として以下の2つの方法があります。

  • SuperSplat
  • PostShot

SuperSplatで大まかに編集し、Postshotで細かいノイズを編集するようにしてます。

SuperSplatとは

SuperSplatの立ち上げ方法

Super Splatは以下のGithubを用いてます。
https://github.com/playcanvas/super-splat

上記のコマンドでSuper-Splatを動かすことができる.

# 初めて環境を作る場合
git clone https://github.com/playcanvas/super-splat.git
cd super-splat
npm i
npm run develop

# 2回目以降
cd super-splat
npm run develop

編集はWebブラウザ(Localhost)で行うことができる.
下記のコードを打ってWebブラウザを立ち上げます.

http://localhost:3000

このような画面が出てきます.

この画面に3DGSで学習したPLYファイルをドラッグ&ドロップしましょう.
すると,以下のようにPLYファイルを読み込まれます.

動作方法

動作方法について

  • 移動は右クリックしながらマウスを動かす
  • ズームはマウスホイール
  • 回転は左クリックしながらマウスを動かす

もし,移動速度が速い場合は,以下の赤枠のSCENEのSCALEの値を大きくすると移動がしやすくなります.

編集方法

右のGUIのBrushをクリックして,画面上を右クリックすると以下のようにPointを選択することができます.

その選択したPointをGUIのDelete Selected Splats Buttonで消すことができます.
下記のように削除することができます.

Brush以外にも以下のようにRect(長方形)でのPointの選択も行うことができます.

しかしBrush・RectのPointの選択は,奥のPointまで選択されてしまうので,注意が必要です.

次にPlaneを使ったPointの削除方法についてです.

GUIのPlaneのRatio Buttonを押すとViewer上に長方形の赤枠が出てきます.

GUIのAdd Buttonを押すとその長方形の上側のPointが選択されます.

大雑把にPointを削除したい場合はBrush・Rect・Planeの方法で削除しましょう.
もし,細かくPointを削除したい場合は,Sphereを使用して削除しましょう.
以下のようにGUIのSphereのRadio Buttonを選択すると,Viewer上に球体が出てきます.
※Sphereを使用する場合,SCENEのScale値をDefaultの1にしないと選択される範囲が変わってしまうので1にしましょう.
この球体の中に入っているPointを選択することができます.

GUIのAdd Buttonを押すとSphere内のPointを選択することができます.

この球体を移動させていき,細かいノイズ(point)を削除していきましょう.

Postshotについて

PostShotは、NeRF・3DGSを生成・使用するためのエンドツーエンドのアプリです。
アプリをダウンロードするだけでNeRF・3DGSを作成できるため、環境構築が必要ありません。
Postshotは、シームレスなワークフローに統合されたNeRFと3DGS技術を使用して、高速でメモリ効率の高い学習を提供します。
学習する際に、Cloudにあげる必要がなく完全にLocalで学習を行えます。
システム要件は、Windows 10以降、Nvidia GPU GeForce RTX 2060、Quadro T400/RTX 4000以上となります。
今回は、Nerfstudioで学習したモデルをPostshotで編集する方法のみ記載します。

Postshotでの編集について

まず、PostshotのHPからアプリをダウンロードしましょう。

ダウンロードして、アプリを開くと次のような画面になります。
PostShot.JPG

次にplyファイルをドラッグ&ドロップしましょう。
ドラッグ&ドロップすると次のように3DGSが可視化されます。
PostShot-Main.PNG

次の赤枠のButtonを押すと原点の表示・非表示を切り替えできます。
PostShot-Origin.PNG

次の赤枠のButtonを押すと点群の表示・非表示を切り替えできます。
PostShot-PointCloud.PNG

次の赤枠のButtonを押し、Viewerを右クリックすると表示された円の中のGaussianを選択できます。
PostShot-SimpleEdit.PNG

この方法だと選択した中のGaussianが下のようにすべて選択されます。
PostShot-SimpleEdit-1.PNG

次の赤枠のDelete Buttonを押すとすべてのGaussianが削除されます。
PostShot-Delete.png

PostShot-SimpleEdited.PNG

次の赤枠のButtonを押すと消す奥行きを設定できます。
PostShot-DepthEdit.PNG

CTRL+マウスホイールで奥行きを設定でき、次のように一部を削除できます。
PostShot-DepthEdit-1.PNG

次の画像は、奥行きを設定し、木を削除しました。
周りのGaussianには影響なく、綺麗に消せていることがわかります。
PostShot-DepthEdited.PNG

このように,学習した3DGSデータを編集することで、より高品質な3DGSのデータを作れます。

AfterEffectでの映像出力方法

次にPostShotで編集したデータをAfterEffectで映像を出力します。Postshotは、統合されたレンダリングと合成のために、Adobe After Effectsに3DGSをImportできます。

始めに、コンポジションを追加します。
new Comp.png

次に、平面レイヤーを追加します。
newFloor.png

追加した平面レイヤーを右クリックしてください。

image.png

右クリックしてエフェクト->Jawset->PostShotを追加してください。
addPostshot.png

Postshotを追加したら、平面レイヤーのエフェクトコントロールからSElect Fileをクリックしてください。
SelectFile.png

クリックしたらPostShotのファイル(pshtファイル)を選択してください。
loadPostShot.PNG

PostShotのファイルを選択すると次のようにViewerを見ることができます。
nagoyaLoad.PNG

次にカメラを追加します。
image.png

カメラ位置姿勢の変更方法は次の図の3つの方法で変更できます。
3DCamera.PNG

任意の位置姿勢にカメラを移動させたら、Keyframeを打ちます。
複数のKeyframeを打って、再生するとカメラ位置姿勢が移動し、それに合わせて3DGSのViewerも更新されます。
SetKeyFrame.png
EndKeyFrame.png

Keyframeの指定が終わったら、書き出しをしましょう。ファイル->書き出し->レンダーキューに追加します。
RenderQue.PNG

動画の出力先を指定してください。
OutputPath.png

出力先を設定したらレンダリングボタンを押してください
Rendering.png

これにより指定したKeyframeに沿った映像を出力できます。

このように,以下の流れを行うことで高品質な3DGSを出力できます。

  1. 撮影
  2. Nerfstudio(Splatfacto)で学習
  3. SuperSplat・PostShotにてノイズ除去
  4. PostShotでAfter Effectsに渡せるファイルへ変換
  5. After Effects にて可視化
  6. 動画出力

今後の展望について

1.高品質化・広範囲化

Mip-SplattingやTRIPS・Nerfstudio(Splatfacto)などオリジナルの3DGSを改良したモデルが続々と発表会されています。

今後も出てくると予想されるため、さまざまなモデルの検証をしていく必要があります。

また、Nerfstudioの環境が現時点では使いやすい(パラメータ調整やViewerなど)ため、パラメータ調整を上手く行えば、より高品質化できます。

3DGSは点群を用いているため、修正が可能(SuperSplat・PostShotなどが現時点で可能)のため、ノイズを除去したり、二つのファイルを上手く結合(Akiya Pluginが現時点で可能)することで、広範囲化もできます。モデルとしてもZip-NeRFやlocalrfなどの広範囲でも可能なNeRFのモデルが出ていることから、3DGSでも同様に広範囲を対応したモデルが出てくると思います。

2.時系列の保存

これまで検証してきた3DGSはすべて静的な対称しか対応していなかったが、4DGS4K4Dなど動的な対称を対応しているモデルも発表されています。

4DGSは単眼カメラでの撮影が可能ではあるが、撮影が難しいという点があります。

複数のカメラを使用した方法Dynamic3DGaussiansがあるが、撮影にはコストがかかります。

そのため、まだ動的な対称を撮影するのは難しいが、近いうちに、ハードウェア面、撮影しやすさ、の面を改良されたモデルが出てくると思っています。

40
19
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
40
19