🚜

nerfstudioでNeRFから360°画像をレンダリングする

2023/03/20に公開

やること

  1. 動画を撮る
  2. nerfstudioで動画からカメラ情報を取り出す
  3. nerfstudioでNeRFを学習する
  4. nerfstudio viewerで学習結果を見る
  5. nerfstudio viewerでカメラ位置とカメラ情報(360°画像)を決める
  6. nerfstudioでレンダリングする

レンダリングのカメラパスの設定方法などは細かく触れませんが,nerfstudioの触り方は一通りわかる気がします.

nerfstudioとは

https://docs.nerf.studio/en/latest/

  • NeRFを簡単に学習して,レンダリングできる
  • いろいろなNeRFモデル(vanilla-nerf, nerfacto, instant-ngp...)が使える

    噂のLERFも今後使えるようになるらしいです
  • いろいろな入力を処理できる

    すご...今回は動画でやりますが,ぜひLiDARデータも入れてみたいですね

nerfstudioで360°画像を作るまで

nerfstudio環境構築

今回はDockerでやります.Pytorchのバージョン合わせとか回避できますし,Docker分からなくてもコマンド叩くだけでできます.
https://docs.nerf.studio/en/latest/quickstart/installation.html#use-docker-image
ここに従うだけです.

  1. Dockerがない人はDocker desktopをインストール
    インストールできたら,Docker desktopを立ち上げて,左下の色がオレンジ(starting)から緑(running)に変化していることを確認
  2. 自分のGPUにあったGPUドライバをダウンロード
  3. dockerイメージをpull
    画像中のコピーボタンを押してコマンドをコピー→powershellなどに貼り付ける
    docker pull dromni/nerfstudio:0.1.19
    
  4. dockerイメージからコンテナを起動
    自分の環境に合わせて/folder/of/your/data/home/<YOUR_USER>/.cache/を書き換えて実行
    docker run --gpus all \                                         # Give the container access to nvidia GPU (required).
            -v /folder/of/your/data:/workspace/ \               # Mount a folder from the local machine into the container to be able to process them (required).
            -v /home/<YOUR_USER>/.cache/:/home/user/.cache/ \   # Mount cache folder to avoid re-downloading of models everytime (recommended).
            -p 7007:7007 \                                      # Map port from local machine to docker container (required to access the web interface/UI).
            --rm \                                              # Remove container after it is closed (recommended).
            -it \                                               # Start container in interactive mode.
            --shm-size=12gb \                                   # Increase memory assigned to container to avoid memory limitations, default is 64 MB (recommended).
            dromni/nerfstudio:<tag>                             # Docker image name if you pulled from docker hub.
            <--- OR --->
            nerfstudio                                          # Docker image tag if you built the image from the Dockerfile by yourself using the command from above. 
    
    例えば私の環境では
    docker run --gpus all -v C:\Users\sakutama\nerfstudio:/workspace/ -v C:\Users\sakutama\nerfstudio\.cache:/home/user/.cache/ -p 7007:7007 --rm -it --shm-size=12gb dromni/nerfstudio:0.1.19
    
    そして
    user@xxxxxxxxxx:/workspace$
    
    のようにコンテナの中に入れれば完了です.

これで,nerfstudio関連のコマンドが自由に使えるコンテナができました

2. nerfstudioで動画からカメラ情報を取り出す

https://docs.nerf.studio/en/latest/quickstart/custom_dataset.html#images-or-video

ns-process-data {images, video} --data {DATA_PATH} --output-dir {PROCESSED_DATA_DIR}

例えば

ns-process-data video --data ./data/nerfstu
dio/lab/video/large.mp4  --output-dir ./data/nerfstudio/lab/

内部でffmpegとCOLMAPが走って,動画を画像群に変換→各画像における三次元のカメラ位置(外部パラメタ)とカメラの内部パラメタ(焦点距離や画角など)を推定してくれています.
1分半の動画を処理するのは5-10分くらいで終わります.

3. nerfstudioでnerfモデルを学習する

https://docs.nerf.studio/en/latest/quickstart/first_nerf.html#training-your-first-model
先ほどデータ処理で,--output-dirに入れたディレクトリを --dataに入れて以下のコマンドを実行

ns-train nerfacto --data data/nerfstudio/lab

nerfactoのところは,お好みのモデルでどうぞ.利用可能なモデルの一覧は

ns-train --help

で確認できます.
学習途中でも,以下のような

Viewer at: https://viewer.nerf.studio/versions/23-03-9-0/?websocket_url=ws://localhost:7007

という表示が出るので,viewerにアクセスします.
トレーニング中でも,データがwebsocketでビューワーに渡っているので,リアルタイムに学習結果が見られます.

15-20分ほどで学習が終わります. ctrl+cで終了と出てくるが,終了しないでviewerに接続.

4. nerfstudio viewerで学習結果を確認する


右上のHide Imagesを押すと,カメラ位置にある画像たちが消えます
一見何も表示されていないように見えるかもしれませんが,

  • スクロールでzoom in/out
  • ドラッグで原点周りにカメラを回転
  • 右クリックドラッグでカメラを平行移動

のように操作して,画像群の真ん中あたりにカメラを移動させると,景色が見えてくると思います.

5. nerfstudio viewerでカメラ位置とカメラ情報(360°画像)を決める

カメラの位置を大体360度画像の中心あたりに移動し,カメラをなるべく水平に向ける.
次に,カメラのパラメタを設定.
下の画像中のように,

  • Resolution ... なんでも良いが2:1(背景に使うならもう何倍か解像度上げてもいいかも)
  • Duration ... 今回は画像を出したいだけなので1で良い
  • FPS ... 今回は画像を一枚出したい(結果2枚になるけど(後述))だけなので1で良い
  • Camera Type ... Equirectangular(正距円筒図法,世界地図のやつね)に設定
    設定できたらADD CAMERAを押す.

この状態でカメラを動かしてカメラを追加して...とやっていくとアニメーションがレンダリングできるわけだが,今回は360°画像が1枚欲しいだけなのでカメラを動かさずにもう一度ADD CAMERA
※カメラ一つじゃダメなの?と思ったけど,何故かカメラパスが書き出されなかったので,同じカメラをもう一度追加する.
少しスクロールしないと見えないかもしれませんが,下の方にCamera0, Camera1と出ています.

6. nerfstudioでレンダリングする

RENDERを押します.

ns-render --load-config outputs/lab/nerfacto/2023-03-19_144950/config.yml --traj filename --camera-path-filename data/nerfstudio/lab/camera_paths/2023-03-19_144950.json --output-path renders/lab/2023-03-19_144950.mp4

言われた通りにコマンドをコピペすると動画が出てきます.今回は画像が欲しい...
なので,
↓のいう通りに,--output-format imagesを最後につけて,--output-pathをmp4から,画像群を保存したいディレクトリに変更.

ns-render --load-config outputs/lab/nerfact
o/2023-03-19_144950/config.yml --traj filename --camera-path-filename dat
a/nerfstudio/lab/camera_paths/2023-03-19_144950.json --output-path render
s/lab/ --output-format images

こんな感じで完了↓

output-pathに指定したディレクトリを見にいくと,レンダリングされています.
わざとちょっと解像度下げてますが,こんな感じです.

7. 【余談】ARとの組み合わせ

https://zenn.dev/sakutama_11/articles/ead557ca54e55b
8th wallのPortalと組み合わせて,いつでも研究室にワープできるようになりました.

まとめ

nerfstudioで動画を学習~レンダリングするまでをまとめました.
360°画像をレンダリングして, a-frameのskyboxに貼り付けてワープを表現しました.

感想

カメラパスいじりや,LiDARデータからの学習も今度やりたいですね

Discussion