Articles cc lab lab LichtFeld Studioを用いた一連の3DGS生成手順とコツをご紹介します(前編)

こんにちは、コンテンツデザイン開発グループリアルタイムチームの菅木です。
 
今回は、以前SNSでご紹介した猫の3DGS生成を事例に、スマホで撮影した動画からSfM→3DGS生成→可視化・編集までの一連の手順とコツをご紹介いたします。

猫の生成結果はこちら

使用するツールは無料で使える物に絞ってご紹介します。3DGS生成までのプロセスをステップバイステップで解説しますので、ぜひご参考にしてください!
また、私が実施する上で、参考になったWebページも適宜掲載していますので、あわせてご参照ください。
※ PC環境によっては、記載通りに動作しない場合があります。
※各ソフトウェアのダウンロード、インストールおよびアカウント作成に関する一切の行為は、利用者自身の責任において実施されるものとし、これに起因するいかなる損害についても、当方は一切の責任を負いかねます。

使用ツールは以下の通りです。
・blender :動画の連番化
・COLMAP :SfM
・Licht Feld Studio :3DGS生成
・SuperSplat :3DGSの可視化・編集(webアプリ)

動画の撮影について

3DGSを生成する際の動画撮影のコツは以下です。

==================================
① 撮影対象に対して横に移動しながらとる。
② ブレが生じないよう、ゆっくりと明るい場所で撮影する。
③ できるだけ明るさの変化が少ないシーンを撮影する。
④ 広い範囲を撮影する場合は同じ場所を2周撮影する。
==================================

動画や写真から3DGSを生成する場合には、SfMによって復元した初期点群とカメラ位置のデータを用意するのが一般的です。SfM は複数の画像から対象物の3次元形状を復元する技術です。図-1のように画像の中に写る同じ場所の特徴点を複数画像で対応付けて、三角測量の要領で特徴点の3次元座標を推定します。実際には、カメラの位置や姿勢も同時に推定するため、複数の特徴点を使ってより複雑な計算が行われています。
3DGSは、このSfMで推定した結果を初期値として、空間上に配置した「ガウス分布(ガウシアン)」の密度や形状を最適化していきます。そのため、SfMを精度よく行うことが、綺麗な3DGSを生成するための重要な工程となります。

「Garbage in, garbage out:ごみを入力するとごみが出力される」という計算機科学における格言があるそうです。どれだけいい3DGSモデルを用いたとしても入力データが悪いと結果もそれなりになってしまうということです。

supersplat_1
図- 1 SfMにおける特徴点のマッチングと座標推定イメージ

①の横に移動しながら撮影する理由は、三角測量の考え方で位置を推定する都合上、各画像に十分な視差が必要だからです。例えば、その場で回転するように撮影した動画は視差が足りず推定精度が悪くなりますので、“カニ歩き”を意識して撮ると成功しやすいと思います。

②③は同じような理由ですが、画像がブレたり、見る場所によって見た目が変わってしまうと、特徴点検出やマッチングが上手くできず、使える画像数が減って精度が落ちてしまいます。また、SfMの際は特徴点不足で使用されないとしても、品質の悪い画像をガウシアン生成に利用してしまうと質の悪い画像も正しい見た目としてガウシアンを最適化しようとするため、浮遊した余計なガウシアン等が多く生成されてしまう原因となります。 シャッタースピードが落ちない明るい場所で撮影する、露出が変わらないように露出固定の設定をする、もしくは露出が変わりづらい明るさが均一な場所で撮影すると上手くいくことが多いです。

④については、広い範囲を撮影する場合、誤差が徐々に蓄積して歪みが生じ、最初の位置に戻ってきても点群がつながらないことがあります。2周撮影しておくと、COLMAP(SfMツール)の Loop Detection オプションにより同じルートが検出され、全体の整合性が取れるように補正されるため、推定精度を高めることができます。
(今回は猫の周りだけですのでLoopDetectionは使用していません。)
 
今回、猫の3DGS生成で使用した動画は以下のものです。

本動画は、手ブレによるボケた画像が含まれた動画になっています。生成時は比較的きれいな画像だけ選別して解析に使用することで生成品質を上げています。ブレのある画像の有無による生成結果の違いについては、後の章で比較します。

動画の連番画像化、画像の間引き・選別

今回は無料で使えるblenderの動画編集機能を用いて動画を連番画像化します。
Pythonのffmpegやその他フリーの動画ソフトで画像化しても問題ありません。

Blenderは下記からインストールできます。
https://www.blender.org/download/

Blenderを開いたら、初めのスプラッシュ画面からビデオ編集を選択します。

supersplat_2

消えてしまった場合は、右上のblenderアイコンから再表示できます。

supersplat_3

下記、追加→動画から連番化する動画を選択します。

supersplat_4

ストリッププロパティから動画のフレーム数を確認します。この動画は1589フレームですね。今回はおおむね500枚程度になるように1/3の画像数に間引いて出力します。

supersplat_5

出力プロパティで、フレーム範囲の終了を先ほど確認した全フレーム数「1589」に、ステップ「3」にして1/3おきの出力とします。出力フォルダを指定し、メディアタイプを「画像」とします。

supersplat_6

レンダーからアニメーションレンダリングを実行すると、連番画像が指定のフォルダに書き出されます。

supersplat_7

スマホなどで動画撮影すると、どうしても手ブレやピンボケしたフレームができてしまうことがあります。この動画でも下図のようなボケた画像が含まれています。
 これらはガウシアンの品質を落とす要因になるので今回は手作業で削除しました。ただし、間引きすぎると画像間で共通して写っている範囲が不足して、画像間の対応付けが上手くいかなくなる場合もあるので、写っている範囲を確認しながら、特に品質が悪いものを間引いています。

supersplat_8

試しに、ボケた画像を間引いた場合と、間引かずに使用した場合で作成した3DGSを比較しました。
 猫のディティールや地面の凹凸を見ると、「ボケた画像あり」の生成結果は、少しぼやけた見た目になっており、3DGS最適化過程でボケた画像も忠実に再現したようです。
因みにですが、「ボケた画像間引き」(左)のスプラット数は約50万点、「ボケた画像あり」(右)が約360万点で生成しています。
 点数をどれだけ増やしても、入力画像の質に大きく左右され、ガウシアンの数を増やすだけでは品質向上には限界があることがよくわかります。
 例えば、レンズフレアや露出の過度な変化なども、それを正として最適化してしまいます。露出変化を抑えるような手法もあるようですが、このような画像が品質を下げる要因になってしまうことは確かだと思います。
 まさに「Garbage in, garbage out」です。

supersplat_9

COLMAPによるSfM

解析に使用する画像の準備が整いましたので、次はSfMの工程です。
まずは、SfMを実行できるCOLMAPというツールをインストールします。

インストール方法や基本的な使い方は下記を参考にしました。
[1] 【Windows】COLMAPのインストールと使い方
[2] 3D Gaussian Splattingのシーン作成・再生の環境構築
[3] 3D Gaussian Splattingの派生版 “EDGS”を試してみる

まず、下記リンク先の、「colmap-x64-windows-cuda.zip」をダウンロードして解凍します。
(CUDAを使わない場合はnocudaの方を使うようです。)
COLMAP: https://github.com/colmap/colmap/releases

zipを解凍すると以下のようなファイルが入っていると思います。
COLMAP.batをダブルクリックで実行するとGUIが立ち上がります。

supersplat_10

ファイルタブからNew projectで新しいプロジェクトを作成します。DatabaseはNewからデータファイルを保存する場所と.dbファイル名を指定します。Imagesは作成した連番画像を保存しているフォルダを指定します。(パスに日本語名が入っていない場所である必要がありそうです。)

supersplat_11

無事読み込めたら次は、特徴点の抽出(Feature extraction)です。
下記を選ぶと設定画面が出ます。

supersplat_12

主要な設定は以下の通りです。基本はデフォルトです。

supersplat_13_1

Camera model:OPENCV
PINHOLEはゆがみのない補正済みの画像に使うようです。ゆがみがある場合RADIALかOPENCVを使うそうですが、OPENCVの方がゆがみ補正のパラメータが多くより柔軟な補正となるようなので、こちらを使います。魚眼の場合はFISHEYE系の専用のモデルがあるようです。
参考:https://colmap.github.io/cameras.html

Shared for all images :ON
カメラのモデルパラメータをすべての画像で共有するかという設定です。今回は1つのカメラで撮影した画像のみですので、より推定精度が上がるようONに設定しています。

Sift.first_octave:0
特徴点を抽出時の縮尺設定のようです。-1だとより細かい特徴まで拾うようになるが低速になるため、中間設定で0とするのが良いようです。[参考3]より。

estimate_affine_shape:OFF
パースによるゆがみを考慮した特徴点抽出ができるそうです。特徴点抽出が上手くいかない場合はONにするとよいみたいです。今回は速度を取ってOFFとします。
参考:https://colmap.github.io/faq.html

設定したら、Extractボタンを押して実行します。
完了したら、次は特徴点のマッチング(Feature matching)です。
下記ボタンを押すと再度設定が開きます。

supersplat_14

いくつか特徴点マッチングの種類があります。

Exhaustive:総当たりでマッチングが計算される。
Sequential:連番で処理される。overlapパラメータの前後フレーム数に対して実行される。
VocabTree:類似画像を検出してマッチングが実行される。

重ね掛けも可能みたいなので、何度か同じ場所が映るような連番画像の場合、ExhaustiveやVocabTreeを追加でかけておくと精度が上がる場合もあるようです。

今回は連番画像として、Sequentialを選択します。
主な設定は以下の通りです。基本はデフォルトです。

supersplat_14_5_1

Loop_detection:OFF
前述の同じ場所を検出して補正してくれる機能です。今回は不要なのでOFFです。

Multiple_models:OFF
複数の構築結果を作るかどうかの設定らしいですが、基本的に一つの場所を構築するのでOFFにします。

guided_matching:OFF
テクスチャが弱いシーンや画像の重なりが少ないシーンにおいて、外れ値のマッチングを削減することができるそうです。特徴点検出の閾値を低くした際に精度の悪い点の発生を抑制するのに役立つのかもしれません。

参考:https://smartdatascan.com/tutorials/gaussian-splatting-windows/colmap/adjusted-parameters/

Runを押すと実行されます。

これで3D再構築の準備が完了しました。
ReconstructionタブからStartReconstrctionを実行します。

supersplat_16

3D再構成とカメラ位置の推定が始まります。

supersplat_17

完了したら、ゆがみ補正した画像とモデルを出力します。
Extractタブから、Undistortionを選択し、output_pathを設定してUndistortボタンで実行します。Output_pathの中にゆがみ補正された画像とSfMの結果が書き出されます。
これでSfMの工程は完了です。

supersplat_18

長くなりましたが、これで3DGSの生成に必要なデータの準備が完了しました。
後編は、Licht Feld Studioを用いた3DGSの生成を実施していきます。