フォーム読み込み中
この記事はソフトバンク アドベントカレンダー2024に参加しています。16日目の記事です。
近年の技術発展は目覚ましく、深層学習の手法を活用することで画像から3Dモデルを簡単に生成できるようになってきました。本記事では、 新規視点生成手法(novel view synthesis)に分類される「3D Gaussian Splatting」について、その技術的な概要を解説し、ローカルPC で動作させてみた結果を紹介します。
3D Gaussian Splatting をローカルPCで検証するにあたり、関連する周辺技術を整理しておくことで実際の検証手順の意味合いが明確にできると思っています。前置きは少し長くなりますが、技術的な背景から順を追ってご紹介します。
新規視点生成手法とは、対象とするシーンや物体を任意の視点からみた場合の情報を生成する手法です。この分野の歴史は古く、1996年に提案された Lumigraph などに代表される手法にまで遡ります。その後、この流れを受けて登場したのが Structure-from-Motion(SfM)と呼ばれる手法です。
SfM は、複数の写真から三次元シーン情報とカメラ位置を再構成する手法で、三次元シーン再構成手法として現在でも広く使用されています。この名称は、移動する(Motion)カメラで撮影した画像を基に形状(Structure)を再構成するという意味合いで付けられているようです(解説:Structure from Motion (SfM) 第一回 SfM の概要とバンドル調整)。なお今回の内容には直接関係しませんが、Shape from Shading(陰影から形状を復元する手法)、Shape from Defocus(ピントを用いて形状を復元する手法)と呼ばれる類似手法も存在します。
SfM の処理の中で、今回の 3D Gaussian Splatting に関係するのは主に以下のステップです。
特徴点のマッチング:抽出した特徴点を画像間で比較し、同じ物体上の同一地点を異なる角度から撮影した場合の対応点を特定します。
三次元情報の再構成:因子分解法もしくはエピポーラ幾何を用いることで、三次元シーン情報とカメラ位置を再構成します。
以上の処理概要を、下図(出典:theia-sfm.org)に示しています。
対象の周囲を移動させながら撮影し、特徴点の抽出とマッチングを行い、さらに再構成処理を行うことで、点群情報を計算させることができます。
深層学習を用いた三次元シーン情報の再構成手法として、まず挙げられるのが Neural Radiance Field(NeRF: Representing Scenes as Neural Radiance Fields for View Synthesis) です。新規視点生成に深層学習を活用する試み自体は2016年頃から行われていた様です(ex. DeepStereo: Learning to Predict New Views from the World’s Imagery)が、2020年に提案された NeRF は、それ以前の従来手法の性能を凌駕する性能を達成し、画期的な技術として注目されています。そのインパクトの大きさから ECCV’20 Best Paper Honorable Mention を受賞しています。
そもそも三次元シーン情報を表現する手法には大きく分けて2つのアプローチがあります。
一つが陽に(直接的に)構造を扱う方法で、もう一つが暗黙的に(間接的に)扱う方法です。ボクセルや点群などは陽に扱う手法に分類され、NeRF は暗黙的にに扱う手法に分類されます。つまりNeRF では、三次元情報を直接的に保存して表現するのではなく、連続関数(ニューラル場)を用いて表現しています。三次元の位置情報と視線方向を入力とすることで、新規視点から見た画像を生成します。
以上の概要を下図(NeRF: Representing Scenes as Neural Radiance Fields for View Synthesis Fig.2より)に示しています。NeRF では「どこからどういった方向で見るか」という情報を処理させることで、任意の視点からみた対象物の情報を生成しています。
いよいよ本題である 3D Gaussian Splatting(以下、3DGS)についての技術的概要に移ります。
深層学習を用いた三次元シーン情報の再構成手法として NeRF と並んで注目されているのが、今回のテーマである “3D Gaussian Splatting for Real-Time Radiance Field Rendering” です。3DGS では三次元シーン情報をガウス分布を用いて表現する手法を採用しており、物体の構造を陽に扱うことが可能である点が NeRF と異なっている点です。
3DGS では、撮影した画像と SfM によって再構成された疎な点群、さらにカメラ位置を入力として対応する三次元ガウス分布を作成します。SfM では色味と位置の情報をもつ疎な点群を計算できるため、それらの情報を用いてガウス分布を初期化します。また各点は透明度α、色情報の球面調和パラメーターを持っており、これらのパラメータを調整することで三次元シーンを再構成します。
以上の処理概要を下図(元論文より)に示しています。実際にはSfM の点群を用いた初期化から射影、ラスタライズ、ガウス分布の複製・分割などを含めた一連の処理を学習の過程で実行していきます。
ここまでで、NeRF や 3DGS について紹介しました。それでは、実際にローカルPCで実行してみます。今回は Mac(MacBook Pro M1、2020、メモリ16 GB)を使用しました。
まず初めに、3D化したい対象物体の画像を撮影します。今回は動画で対象物を撮影し、その動画をフレームごとに切り出して処理する方法を採用しました。対象物として、家にあったラバーダックを机の上において、ぐるっと対象物全体が映るように1分程度の動画を撮影(iPhone14 で撮影)しました。
撮影した動画からフレームを切り出すには、以下の ffmpeg コマンドを使用します:
ffmpeg -i ${INPUT_MOVIE} -vf fps=5 ${OUTPUT_PATH}/output_%04d.png
本来は手ブレした画像を省いたり、切り出すFPSを調整したりと色々と考えることはあると思いますが、今回は特に深追いはしていません。
colmap \
feature_extractor \
--image_path ${DATA_PATH} \
--database_path ${OUTPUT_PATH}/database.db \
--ImageReader.single_camera 1 \
--ImageReader.camera_model PINHOLE
このコマンドを実行すると、指定した OUTPUT_PATH 以下に database.db というファイルが生成され、ここに計算結果が保存されていきます。このファイルは SQLite のファイルですので、SQLite のコマンドやツールを用いれば中身を直接確認することも可能です。
次に、抽出した各画像の特徴点を基に、各画像間で特徴点のマッチングを行います。以下の コマンドを実行します。DATA_PATH は引き続き先程指定したものと同じパスを使用します。
colmap \
exhaustive_matcher \
--database_path ${DATA_PATH}/colmap/distorted/database.db
この処理は少し負荷がかかるらしく、私の手元の mac ではスクリプト実行中はファンが音を立てていました。
特徴点マッチングの結果を用いてバンドル調整を行い、三次元情報を再構成します。以下のコマンドを実行します。
colmap \
mapper \
--image_path ${DATA_PATH}/images/ \
--database_path ${DATA_PATH}/colmap/distorted/database.db \
--output_path ${DATA_PATH}/colmap/distorted/sparse \
--Mapper.ba_global_function_tolerance=0.000001
このステップにより、対応する特徴点の位置情報をもとに三次元シーンが再構成されます。
カメラの内部パラメータによる画像の歪みを補正します。以下のコマンドを使用します。
colmap \
image_undistorter \
--image_path ${DATA_PATH}/images \
--input_path ${DATA_PATH}/colmap/distorted/sparse/0 \
--output_path ${DATA_PATH}/colmap/undistorted \
--output_type COLMAP
ここまでで COLMAP を用いた SfM に関する前処理が完了しました。後段のスクリプトで使用するために生成されたデータを以下のディレクトリ構成に整理しておきます。
.
├── images/
├── cameras.bin
├── images.bin
└── points3D.bin
3DGS を実行するためのツールは公式リポジトリを含め各種提供されていますが、今回はローカル端末でも軽量に動作する OpenSplat を使用しました。
OpenSplat は C++ で実装されているため、利用するにはビルドが必要です。その際に、LibTorch(PyTorch を C++ から利用するためのライブラリ)をインストールする必要があるため、README に従ってインストールします。LibTorch のインストールには PyTorch 公式サイト へアクセスし、
LibTorch とその他該当する環境を選択し、「Run this Command」に表示されているコマンドを実行します。libtorch-macos-arm64-2.5.1.zip をダウンロードした後、インストールしたい場所へ配置します。どこでもよいのですが今回は作業ディレクトリへ配置しました。その後、LibTorch をインストールしたパスを指定しつつ以下のコマンドでビルドします。
cd build
cmake -DCMAKE_PREFIX_PATH=/path/to/OpenSplat/libtorch/ .. && make -j$(nproc)
ビルドが成功すると、opensplat という名前の実行ファイルが生成されます。これで環境構築完了です。
環境構築が完了したら、いよいよ 3DGS の実行へと移ります。SfM で前処理を行ったディレクトリを指定し、以下のコマンドを実行します:
./opensplat --input_dir /path/to/sfm_output -n 2000
そして処理が終わるまでしばらく放置しておくと、splat.ply というファイルが生成されます。あとはこのファイルを眺めるだけ!と、言いたいところですが、前処理の甘さだったり動画像の質や様々な要因で、全体的にぼやっとしたノイズが乗っています。見栄えをよくするために SuperSplat と呼ばれる編集ツールを用いて、ラバーダック部分だけを抽出しておきます。
このままだと座標軸や大きさなどが意図していないため、そのあたりも修正しておきます。SpuerSplat で後処理をした結果が下図です。
SuperSplat 上でも作成した3Dモデルをグリグリと動かして閲覧することはできるのですが、最後に「3Dモデルを作ったよ」と分かるようなものを作って終わりにしたいと思います。そこで、Three.js でデータを描画できる GaussianSplats3D を用いて、ラバーダックが回転するディスプレイ用動画を作成してみました。
こうして、手元にあったラバーダックを無事3Dモデル化することができました。
実は既に、 3DGS はスマートフォンでも手軽に体験できる時代になっています。スマホ向けアプリの
などが有名です。特に Scaniverse では、2024年8月にリリースされたバージョン 4.0.0 にて、作成した3Dモデルをマップ上にアップロードできるプラットフォーム機能が追加されました(リリース)。このようなツールや機能の進化によって、今後ますます 3D モデリングは身近なものとなり、より多くの人に活用される時代がくると思っています。
本記事に限らず、「3D Gaussian Splatting」や関連するキーワードで検索すると、様々な方が取り組んでいる事例を発見できることと思います。今後も目が離せない分野であることは間違いないので、引き続きウォッチしていきたいと思います!
ソフトバンク アドベントカレンダー 17日目もおたのしみに!
条件に該当するページがございません