RTX 5070 Ti環境でNerfstudio + Gaussian Splattingを動かしてみた記録【WSL2 / CUDA 12.8 / Ubuntu 24.04】

※本記事は、私が実際に試行錯誤しながら構築した内容を整理した備忘録です。途中かなりハマりましたが、最終的にはGaussian Splattingの学習・表示まで動作確認できました。同じようにRTX 50シリーズ環境で困っている方の参考になれば幸いです。

はじめに

最近話題の3D Gaussian Splattingを、自宅PC環境で動かしてみました。最終的にはNerfstudio上で学習を完了し、ブラウザ上で3D空間を自由に移動できるところまで確認できました。

特にRTX 50シリーズは比較的新しいBlackwell世代GPUということもあり、CUDAやPyTorch周りでかなり苦戦しました。古い構成記事の通りに進めても動かない箇所があり、本記事では「最終的に実際に動いた構成」と「途中でハマったポイント」を整理しておきます。なお、エジプト旅行の際に私のスマホ(AQUOS SENSE 10)でアブ・シンベル小神殿を通常撮影した動画を用いています。

実際に成功した環境

  • OS: Windows 11
  • WSL2: Ubuntu 24.04.4 LTS
  • GPU: NVIDIA GeForce RTX 5070 Ti
  • VRAM: 16GB
  • NVIDIA Driver: 596.36
  • Python: 3.11.15
  • PyTorch: 2.12.0.dev + cu128
  • CUDA Runtime: 12.8
  • Nerfstudio: 1.1.5
  • COLMAP: 3.9.1

Windows側に最新のNVIDIA Driverを導入した状態で、WSL2上にUbuntuを構築して作業しています。

なお、最終的にGaussian Splatting自体は正常に動作しましたが、COLMAPはログ上「without CUDA」と表示されており、CPU版として動いていました。それでも学習・再構成自体は問題なく進行しました。

CUDA周りでかなりハマった

RTX 50シリーズは比較的新しいGPUのため、古いCUDA / PyTorch構成の記事をそのまま真似するとかなり苦戦しました。

特に混乱したのが、

  • CUDA Toolkitを入れたつもりなのにnvccが見つからない
  • PyTorch CUDAとCUDA Toolkitの違いが分かりにくい
  • CUDAバージョン不整合
  • Pythonバージョン差異

などです。

実際には、PyTorch側のCUDA Runtimeは正常動作しており、GPU学習自体は動いていました。一方でnvccだけが壊れている(PATHが通っていない)状態になっていました。

つまり、

python -c "import torch; print(torch.cuda.is_available())"

ではTrueになる一方、

nvcc --version

が失敗する状態でした。PyTorchのCUDA RuntimeとCUDA Toolkitは別物のようです。

このあたりはかなり混乱しやすいポイントだと思います。

Minicondaの導入

まずはWSL2上にMinicondaを導入しました。

wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh bash Miniconda3-latest-Linux-x86_64.sh

インストール後はシェルを再読み込み。

source ~/.bashrc

Python環境作成

conda create -n nerf python=3.11 -y 
conda activate nerf

途中でAnaconda Terms of Serviceエラーが出ました。

conda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/main conda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/r

CUDA Toolkit 12.8の導入

RTX 5070 Ti環境ではCUDA 12.8系を利用しました。

sudo apt update 
sudo apt install -y cuda-toolkit-12-8

ただし、インストール後も最初は

nvcc --version

で以下のようなエラーが出ました。

-bash: /usr/bin/nvcc: No such file or directory

これはCUDA Toolkit自体は入っているものの、PATHが通っていない状態でした。

そのため、~/.bashrcに以下を追加。

export PATH=/usr/local/cuda-12.8/bin:$PATH export LD_LIBRARY_PATH=/usr/local/cuda-12.8/lib64:$LD_LIBRARY_PATH

その後、

source ~/.bashrc

を実行してPATHを反映しました。

PyTorchのインストール

CUDA 12.8対応版のPyTorchをインストール。

pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu128

GPU認識確認。

python -c "import torch; print(torch.cuda.is_available())"

Trueが返ればOKです。

Nerfstudioのインストール

pip install nerfstudio ns-install-cli

COLMAPとffmpegも必要だったため、以下を導入しました。

sudo apt install colmap ffmpeg

動画から画像切り出し

今回はスマートフォンで撮影した動画から画像を切り出して学習させました。

mkdir images ffmpeg -i input.mp4 -vf fps=1 images/frame_%04d.jpg

fps=1では画像枚数が少なく、細部が不足する印象がありました。その後fpsを上げて数千枚規模でも試しました。

ただし、単純にfpsを上げれば良いわけではなく、重複画像や微ブレ画像が増える問題もありました。

Gaussian Splatting実行

以下で前処理と学習を実行。

ns-process-data images --data images --output-dir processed ns-train splatfacto --data processed

最終的には以下のように学習完了まで進みました。

🎉 Training Finished 🎉

ブラウザで以下にアクセスすると、3D空間を確認できます。

http://localhost:7007

私の環境で確認した画像は下記(3D画像のスクリーンショット)

3Dガウシアンスプラッティング

実際に生成してみた感想

実際に生成された3D空間は、「本当に空間になっている…!」という感動がある一方、まだかなりモヤモヤ感や破綻も目立ちました。

特に、

  • 壁面ディテールが溶ける
  • カメラ移動時に煙のようなノイズが出る
  • 一部形状が崩れる

といった問題がありました。

ただし、これはGaussian Splattingでは比較的よくある現象で、特に以下の影響が大きいようです。

  • 動画由来の微小ブレ
  • モーションブラー
  • フレーム重複過多
  • 被写体距離変化不足
  • 暗所ノイズ

「動画では綺麗」なのに崩れる理由

動画を見ていると、人間の脳が時間方向に情報を補完するため、多少ブレていても自然に見えます。

しかしGaussian Splattingでは、各フレームを静止画として幾何学的に整合させる必要があります。そのため、人間には気にならない程度の微ブレでも、3D再構成ではノイズ源になることがあります。

逆に言えば、撮影方法やフレーム選別を工夫すれば、かなり改善余地はありそうです。

途中で試したがうまくいかなかったこと

  • 古いCUDA記事をそのまま使う
  • CUDA Toolkit導入後にPATHを通さない
  • fpsを極端に高くする
  • ブレ画像を大量投入する
  • 「動画で綺麗だから静止画も綺麗」と考える

特に、単純にfpsを上げるだけでは改善せず、「高品質なフレームを適度な間隔で抽出する」方が重要そうでした。

fps=5 + blur除去 + 類似画像除去でかなり改善

その後、単純にfpsを上げるだけではなく、「ブレ画像除去」と「類似画像除去」を組み合わせることで、かなり品質改善できました。

最初はfps=1で抽出した画像だけで学習していましたが、細部が不足しやすく、特に神殿内部の壁画や柱のディテールが崩れやすい状態でした。

そこで今回は、動画からfps=5で大量にフレーム抽出し、その後に「ブレ除去」「重複画像除去」を行う構成に変更しました。

実際の処理フロー

  • 動画からfps=5で画像抽出
  • OpenCVでblur判定
  • 類似画像除去
  • COLMAP再実行
  • Gaussian Splatting再学習

動画から高fpsで画像抽出

まずはffmpegでfps=5として画像を大量抽出しました。

mkdir -p retry_fps5/images_raw

ffmpeg -i 260401_052708.mp4 \
-vf fps=5 \
retry_fps5/images_raw/frame_%06d.jpg

結果として、約6分の動画から1838枚の画像が生成されました。

ただし、この状態では「ほぼ同じ画像」や「微妙にブレた画像」が大量に混ざっています。

Gaussian Splattingでは、画像枚数が多ければ良いわけではありません。むしろ低品質画像が増えると、煙のようなノイズ(floaters)が増えることがあります。

blur除去

次に、OpenCVのLaplacian varianceを利用してブレ画像を除外しました。

Gaussian Splattingでは、人間には気にならない程度の微ブレでも、3D空間上ではノイズ源になります。

特にスマートフォン動画では、動画として見ると綺麗でも、静止画単位では微妙にブレているケースがかなり多いです。

今回はPython + OpenCVで簡易的なblur除去スクリプトを作成しました。

python blur_filter.py

1838枚 → 1469枚まで減少しました。

つまり、約20%程度の画像が「ブレ気味」と判定されたことになります。

実際に使用したblur除去スクリプト

今回はOpenCVのLaplacian varianceを利用して、ブレ画像を自動除外しました。

Laplacian varianceは「画像内のエッジ量」を利用した簡易的なブレ判定手法です。ブレた画像は輪郭情報が減るため、スコアが低下します。

以下が実際に使用した簡易スクリプトです。

import cv2
import os
import shutil
from tqdm import tqdm

input_dir = "retry_fps5/images_raw"
output_dir = "retry_fps5/images_sharp"

os.makedirs(output_dir, exist_ok=True)

threshold = 80

files = sorted(os.listdir(input_dir))

for file in tqdm(files):
    path = os.path.join(input_dir, file)

    img = cv2.imread(path)

    if img is None:
        continue

    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    score = cv2.Laplacian(gray, cv2.CV_64F).var()

    if score > threshold:
        shutil.copy(path, os.path.join(output_dir, file))

threshold = 80 の値を上げるほど、より厳しくブレ画像を除外できます。

ただし、厳しくしすぎると必要な画像まで消えてしまい、逆に再構成品質が悪化する場合もありました。

類似画像除去

さらに、ほぼ同じ構図の画像を削除しました。

fpsを上げると、カメラ位置がほぼ変化していないフレームが大量発生します。

Gaussian Splattingでは、「微妙に違う大量画像」より、「適度に位置が変化した画像」の方が重要です。

python dedupe.py

1469枚 → 1385枚まで削減されました。

除去枚数は84枚でしたが、結果的にはかなり品質改善につながりました。

実際に使用した類似画像除去スクリプト

次に、Perceptual Hash(pHash)を利用して類似画像を除去しました。

fpsを上げると、ほぼ同じ構図の画像が大量発生します。Gaussian Splattingでは、位置変化の少ない大量画像はあまり効果がなく、むしろノイズ源になる場合があります。

今回はPython + imagehashを利用して、直前フレームとの差分を比較し、類似画像を除外しました。

import os
import shutil
from PIL import Image
import imagehash
from tqdm import tqdm

input_dir = "retry_fps5/images_sharp"
output_dir = "retry_fps5/images_dedup"

os.makedirs(output_dir, exist_ok=True)

files = sorted(os.listdir(input_dir))

last_hash = None
kept = 0
removed = 0

THRESHOLD = 4

for f in tqdm(files):
    path = os.path.join(input_dir, f)

    try:
        img = Image.open(path).convert("RGB")
        h = imagehash.phash(img)

        if last_hash is None:
            shutil.copy(path, os.path.join(output_dir, f))
            last_hash = h
            kept += 1
            continue

        diff = h - last_hash

        if diff > THRESHOLD:
            shutil.copy(path, os.path.join(output_dir, f))
            last_hash = h
            kept += 1
        else:
            removed += 1

    except:
        pass

print("kept:", kept)
print("removed:", removed)

THRESHOLD = 4 の値を小さくするほど、より厳しく類似画像を除去できます。

ただし、厳しくしすぎると必要な視点変化まで消えてしまい、COLMAPの位置推定が不安定になる場合もありました。

今回は「直前フレームとの比較」のみを行うシンプルな構成ですが、それでもかなりの重複画像を削減できました。

COLMAP再実行

その後、Nerfstudioの前処理を再実行しました。

export QT_QPA_PLATFORM=offscreen

ns-process-data images \
--data retry_fps5/images_dedup \
--output-dir retry_fps5/processed

WSL2環境ではQt関連エラーが出たため、QT_QPA_PLATFORM=offscreenを指定しています。

今回かなり画像枚数が多かったため、COLMAP処理には非常に時間がかかりました。

実際にかかった処理時間

処理時間
fps=5画像抽出約6分
blur除去約56秒
類似画像除去約46秒
COLMAP Feature Extract約13分
COLMAP Feature Match約11時間
COLMAP Bundle Adjustment約22時間
Refine Intrinsics約20分
Gaussian Splatting学習約6時間

特にCOLMAPのBundle Adjustmentが非常に重く、CPU使用率90%以上で20時間以上動作していました。

Feature Extract自体はGPU使用ログが出ており、Bundle Adjustmentなど一部処理がCPU中心になっていたため、ここが最大ボトルネックになっていました。

結果はかなり改善

3Dガウシアンスプラッティング

結果として、以前よりかなり空間が安定しました。

  • 柱の形状崩れ減少
  • ヒエログリフの輪郭改善
  • 壁面ディテール改善
  • 空間奥行き改善
  • モヤモヤ感軽減

特に印象的だったのは、「単純にfpsを増やす」のではなく、「低品質フレームを減らす」方が重要だった点です。

Gaussian Splattingでは、画像枚数よりも「位置変化のある高品質画像」がかなり重要だと感じました。

それでも一部には煙のようなノイズ(floaters)が残っており、暗所ノイズや微小ブレの影響はまだ大きそうです。

生成したGaussian Splattingデータ

学習後に生成された splat.ply をSuperSplatで表示すると、ブラウザ上で3D空間を自由に移動できます。

Gaussian Splattingの実データに興味がある方向けに、今回生成したPLYファイルも公開しておきます。

splat.ply をダウンロード

上記PLYファイルをダウンロードしてSuperSplat公式にドラッグアンドドロップすると見れます。

今後試したいこと

  • より厳しいblur除去
  • ブレ判定による低品質画像除外
  • fps最適化
  • COLMAPパラメータ調整
  • GPU版COLMAP導入
  • 撮影時の手ブレ抑制
  • 被写体を円を描くように撮影

Gaussian Splattingは、動くだけでもかなり面白く、巨大建築や旅行記録を3D空間として残せる可能性があります。特にエジプト神殿のような遺跡を空間丸ごと記録できるのはかなり夢のある技術だと感じました。

終わりに

今回はRTX 5070 Ti + WSL2 + Nerfstudio環境でGaussian Splattingを動かすところまでをまとめました。途中かなりハマりましたが、最終的にはブラウザ上で自由に移動できる3D空間を生成できました。

今後は、動画撮影方法やフレーム選別、ブレ除去などを改善しながら、より高品質な3D再構成を目指していきたいと思います。

00votes
Article Rating
Subscribe
Notify of
guest

CAPTCHA


0 Comments
Oldest
NewestMost Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x
タイトルとURLをコピーしました