※本記事は、私が実際に試行錯誤しながら構築した内容を整理した備忘録です。途中かなりハマりましたが、最終的にはGaussian Splattingの学習・表示まで動作確認できました。同じようにRTX 50シリーズ環境で困っている方の参考になれば幸いです。
- はじめに
- 実際に成功した環境
- CUDA周りでかなりハマった
- Minicondaの導入
- Python環境作成
- CUDA Toolkit 12.8の導入
- PyTorchのインストール
- Nerfstudioのインストール
- 動画から画像切り出し
- Gaussian Splatting実行
- 実際に生成してみた感想
- 「動画では綺麗」なのに崩れる理由
- 途中で試したがうまくいかなかったこと
- fps=5 + blur除去 + 類似画像除去でかなり改善
- 実際の処理フロー
- 動画から高fpsで画像抽出
- blur除去
- 実際に使用したblur除去スクリプト
- 類似画像除去
- 実際に使用した類似画像除去スクリプト
- COLMAP再実行
- 実際にかかった処理時間
- 結果はかなり改善
- 生成したGaussian Splattingデータ
- 今後試したいこと
- 終わりに
はじめに
最近話題の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 ~/.bashrcPython環境作成
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/rCUDA 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/cu128GPU認識確認。
python -c "import torch; print(torch.cuda.is_available())"Trueが返ればOKです。
Nerfstudioのインストール
pip install nerfstudio ns-install-cliCOLMAPとffmpegも必要だったため、以下を導入しました。
sudo apt install colmap ffmpeg動画から画像切り出し
今回はスマートフォンで撮影した動画から画像を切り出して学習させました。
mkdir images ffmpeg -i input.mp4 -vf fps=1 images/frame_%04d.jpgfps=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空間は、「本当に空間になっている…!」という感動がある一方、まだかなりモヤモヤ感や破綻も目立ちました。
特に、
- 壁面ディテールが溶ける
- カメラ移動時に煙のようなノイズが出る
- 一部形状が崩れる
といった問題がありました。
ただし、これは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.py1838枚 → 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.py1469枚 → 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/processedWSL2環境では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中心になっていたため、ここが最大ボトルネックになっていました。
結果はかなり改善
結果として、以前よりかなり空間が安定しました。
- 柱の形状崩れ減少
- ヒエログリフの輪郭改善
- 壁面ディテール改善
- 空間奥行き改善
- モヤモヤ感軽減
特に印象的だったのは、「単純にfpsを増やす」のではなく、「低品質フレームを減らす」方が重要だった点です。
Gaussian Splattingでは、画像枚数よりも「位置変化のある高品質画像」がかなり重要だと感じました。
それでも一部には煙のようなノイズ(floaters)が残っており、暗所ノイズや微小ブレの影響はまだ大きそうです。
生成したGaussian Splattingデータ
学習後に生成された splat.ply をSuperSplatで表示すると、ブラウザ上で3D空間を自由に移動できます。
Gaussian Splattingの実データに興味がある方向けに、今回生成したPLYファイルも公開しておきます。
上記PLYファイルをダウンロードしてSuperSplat公式にドラッグアンドドロップすると見れます。
今後試したいこと
- より厳しいblur除去
- ブレ判定による低品質画像除外
- fps最適化
- COLMAPパラメータ調整
- GPU版COLMAP導入
- 撮影時の手ブレ抑制
- 被写体を円を描くように撮影
Gaussian Splattingは、動くだけでもかなり面白く、巨大建築や旅行記録を3D空間として残せる可能性があります。特にエジプト神殿のような遺跡を空間丸ごと記録できるのはかなり夢のある技術だと感じました。
終わりに
今回はRTX 5070 Ti + WSL2 + Nerfstudio環境でGaussian Splattingを動かすところまでをまとめました。途中かなりハマりましたが、最終的にはブラウザ上で自由に移動できる3D空間を生成できました。
今後は、動画撮影方法やフレーム選別、ブレ除去などを改善しながら、より高品質な3D再構成を目指していきたいと思います。




