STYLY社内ハッカソンでGaussianSplattingをやってみた

# 株式会社STYLY社内ハッカソン

去る、1/10,1/11にSTYLY社内でハッカソンが開催されました。お題は「なんでもOK！」ということで、私は最近気になっていたGaussianSplattingについて調べてみました。

# GaussianSplattingって何？

GaussianSplattingとはSIGGRAPH 2023でBernhard Kerbl,Georgios Kopanasにより発表されたnovel view synthesisの手法です。超平たく言うと、

**複数の画像から"3Dモデルっぽいもの"を出力する手法です。**

3D Gaussian Splatting for Real-Time Radiance Field Rendering
https://repo-sam.inria.fr/fungraph/3d-gaussian-splatting/

実際の出力結果はこんな感じです。

![Videotogif (4).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139643/edb13867-2f3b-4ec8-e0c1-45c863093159.gif)

動画バージョンは[こちら](https://repo-sam.inria.fr/fungraph/3d-gaussian-splatting/content/videos/bicycle.mp4)


以下のツイートから、私が学習させたGaussianSplattingのモデルをブラウザから閲覧できます。

<blockquote class="twitter-tweet" data-media-max-width="560"><p lang="ja" dir="ltr">GaussianSplattingをCOLMAPのサンプルから出したやつ。前処理して111枚からの書き出し。実行はColabでT4で2時間ぐらい。<br>ちょっと要らない部分削ってるけど、細部がエグイ。<br>いやぁ本家のクオリティビビる。<br><br>↓URLからWebで見れるようにしました<a href="https://t.co/WPRctkZ6Kg">https://t.co/WPRctkZ6Kg</a> <a href="https://t.co/Uc8FxwWHhR">pic.twitter.com/Uc8FxwWHhR</a></p>&mdash; こたうち　さんさん (@kotauchisunsun) <a href="https://twitter.com/kotauchisunsun/status/1744296736439533655?ref_src=twsrc%5Etfw">January 8, 2024</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


上記のgif画像は、カメラの映像ではなく、機械学習のモデルから出力されたものです。
この手法は何がスゴイか。というと、

- 他の最新手法(MipNeRF360)と同じくらい綺麗な画像が出力できる
- 137FPSでレンダリングできる(MipNeRFだと0.07FPS)
- 学習時間が38分(MipNeRFだと48時間)

という、**超綺麗な3Dモデルっぽいものを超高速に超短時間で出力できる手法**です。

![Artboard 19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139643/9da40ba2-532d-cfbf-e8ce-800f0d1fb19b.png)

![Artboard 22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139643/78cc44b7-d5db-3d71-32eb-7bd0ac35b273.png)


# フォトグラメトリとの違い

このように画像から"3Dモデルっぽいもの"を出力する手法として、一般的に「フォトグラメトリ」という手法があります。過去に私は[「他人のGPUでフォトグラメトリしたい！」](https://qiita.com/kotauchisunsun/items/9e3444faec734ddedcb5)という記事を書いていますが、GaussianSplattingはフォトグラメトリとは少し異なります。

フォトグラメトリ、日本語だと写真測量法と言いますが、これを[Wikipedia](https://ja.wikipedia.org/wiki/%E5%86%99%E7%9C%9F%E6%B8%AC%E9%87%8F%E6%B3%95)で調べると、

>写真測量法 (しゃしんそくりょうほう 英: Photogrammetry) とは、写真画像から対象物の幾何学特性を得る方法である。写真測量法の歴史は現代写真技術と同じくらい古く、起源は19世紀半ばに遡る。フォトグラメトリとも呼ばれるが、こちらは狭義に、デジタルカメラ等で多面的に撮影した複数のデジタル写真をコンピュータで画像解析し、3次元コンピュータグラフィックス等を得るプロセスを指す言葉として用いられる。

とあります。**フォトグラメトリは多数の画像を解析をして、ポリゴン化された3Dモデルを出力する方法**と捉えることが出来ます。
一方で、GaussianSplattingは論文上ではNovel View Synthesisの手法だと書かれています。Novel View Synthesisを[Wikipedia](https://en.wikipedia.org/wiki/View_synthesis)で引くと(Google翻訳)

> コンピュータ グラフィックスにおいて、 ビュー合成、または新規ビュー合成(novel view synthesis)は、利用可能な情報が異なる視点から撮影された写真のみである場合に、特定の視点から特定の被写体またはシーンの画像を生成するタスクです。

と書かれています。**Novel View Synthesisにおいて、3Dモデルが出力されることは必須ではありません(私見)。** 近い手法であれば、NeRFと呼ばれる技術も特に内部的に3Dモデルを生成しているわけではありません。複数の画像を入力された時、その入力に無い、別の視点からの画像を生成手法である。という、割と大まかな概念です。ある意味で、Novel View SynthesisはPhotogrammetryより大きな分類である。とも捉えられると思います。したがって、**GaussianSplattingを行うと、確かに綺麗でリアルな合成画像は手に入りますが、3Dモデルは基本的には出力されません。**

# Gaussian Splattingの概要

先ほど、フォトグラメトリとGaussianSplattingは似て非なるものである。という話をしました。しかし、色々読んでいくと、手法の流れはかなり似たものがあります。かなり大雑把に書きますが、

1. 画像から特徴点の抽出
2. 画像同士の特徴点のマッチング 
3. カメラ位置の推定
4. 3Dモデル?生成

となっており、この視点で見るとほぼフォトグラメトリとGaussianSplattingは同じです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139643/61dc73e5-4b1f-ed97-b0b9-dc1913903db7.png)

　では、何が違うかというと、3Dモデルの形式です。一般的にフォトグラメトリというものは、良く知られているobjやfbxなど、3Dモデルをポリゴンとして出力しますが、GaussianSplattingでは３次元ガウス関数で表現しています。この3次元ガウス関数で表しているため、3Dモデルに出力できない。という話です。

　では、3次元ガウス関数とは何か。というと、中心の色が濃く、周りの色がぼんやりとしたα値を持つ楕円状の点です。これをx,y,z軸方向に伸ばしたり、縮めたり、回転させたり、色を変えたり、透明度を変えます。この3次元ガウス関数を多数重ねることで3Dモデルを表現します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139643/adc8385c-a60e-1fb3-ca1d-c519408f8f32.png)

以下は実際のGaussianSplattingで生成された画像です。生成例を見ると分かりやすいですが、細い楕円状のものや、針状のモノが見えると思います。これらが1つの3次元ガウス関数となっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139643/7def4091-bde3-d097-037e-e3518d7b2de8.png)

**この3次元ガウス関数を多量に配置し、それを非常に高精度に高速に最適化することで、美麗な出力を得ることが出来る巧妙な方法がGaussianSplattingとなっています。**

# STYLYへGaussianSplattingを導入？

GaussianSplattingの表示機能をSTYLYに実装することを考えてみたとき、現状でどれくらい実現することが出来るでしょうか？

https://github.com/aras-p/UnityGaussianSplatting

UnityGaussianSplattingというライブラリがあったので、これをSTYLYへ導入を試みました。結果、残念ながら導入後のUnityプロジェクトをビルドできませんでした。理由として

1. 依存ライブラリにburst1.8.8があったこと
2. Mobileでは動かなかったこと

という2つがあり、burst1.8.8はUnity2022で導入されたAPIを内部的に利用しているため、Unity2019系でビルドが不可能でした。また、公式のドキュメントでは、

>  Note that the project requires DX12 or Vulkan on Windows, i.e. DX11 will not work. This is not tested at all on mobile/web, and probably does not work there.

とあり、もし導入できてもWindows以外のプラットフォームで動かない。という結果でした。

# GaussianSplatting投稿・共有サイトを作ってみた

<blockquote class="twitter-tweet" data-media-max-width="560"><p lang="ja" dir="ltr">最近、ハッカソンで作ったやつ。自分で学習させたGaussianSplattingのモデルを見たり、共有出来たりする投稿サイトが無いので、自分でサーバーを建てて作った。 <a href="https://t.co/tqb5CpeD0k">pic.twitter.com/tqb5CpeD0k</a></p>&mdash; こたうち　さんさん (@kotauchisunsun) <a href="https://twitter.com/kotauchisunsun/status/1751491691763425397?ref_src=twsrc%5Etfw">January 28, 2024</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

トップページのURL
https://gs-share.paas.facevtuber.com/

実際の閲覧ページはこんな感じです。
https://gs-share.paas.facevtuber.com/?mode=preview&id=8f94eac1-6292-46c7-bc4c-ed282dba20b2

ハッカソンクオリティなので、しばらくしたら閉じるかもです。

サーバーの構成はこんな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139643/9f7aa789-62e8-3257-75f7-76ddd164fc05.png)

日本では割とマイナーなCaproverという自前でPaaS環境が立てられるOSSを使っています。このCaprover自体がとても良いのでそれはそれで記事を書きたい。その上に、ファイルストレージとしてminio(S3互換のOSS)とユーザーのデータを保存するmongoDBをDockerコンテナとして立てています。アプリケーション自体はsteamlitでサクッと作ってしまい、GaussianSplatting自体の表示は、[playcanvas/viewer](https://playcanvas.com/viewer)を使っています。

なぜこんなサイトを作ったか。というと、ある問題意識がありました。
今、LumaAIやPolyCamなど、画像をアップロードするだけで、GaussianSplattingのモデルを生成し、公開できるお手軽なサイトが増えてきています。しかし、一方で、 **自前でGaussianSplattingを学習させた場合、そのデータを手軽に公開出来るサイトがないな。** と思いました。そのため、パッとアップロードして、サッと他人に共有できるサイトあったら便利かな？と思って作ってみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139643/5a43a912-e7b7-3e72-784e-7f39e70166f5.png)

　久々にぬるっとWebサービスを作りましたが、なんとかなるもんだなぁ。という感じでした。ローカルで適当なWebの面を作る。というのは割とありますが、他人が触れるレベルまで作るものをフルスクラッチするのは久々でした。しかし、今、Webの面を作るならVercelやNext.jsかなぁとか思うのですが、そういう苦手なところに時間かけてられないなぁ。と思った結果、手癖でstreamlitに手を出しましたが、雑ながら認証機能を作りこむのは結構大変でした。本来、streamlitは認証機構を入れるような代物ではないので、ものすごくバッドハック的に作りこんだ感じがあります。これはこれでハッカソンっぽさはありますが。とはいうものの、streamlitは便利で、適当にPCで触れるようにしたらレスポンシブ対応もそこそこやってくれるので、スマホでもそこそこ触れるようになる。というのは、私のようなズボラには結構便利だったりします。

# 感想

　紆余曲折あったなぁ。という感じでした。GaussianSplattingは触る気はなくて、別の機械学習のOSSを触ってるうちに、うちのYORIMIYAがGaussianSplattingを触ってるのを見て、じゃあ私もやるかーと思ってやったが運の尽きで、のめりこんでしまいました。また、STYLYにGaussianSplattingを入れるのも難しいなぁという結論になると、何かしらオチがつかないな・・・と思った結果、Webアプリの方へ話を持っていく。というのも中々自分でやってて意味不明だなぁ。みたいなことを思いながら発表資料を作りこんでいました。
 　Webアプリもさっくり作れた。というわけではなく、もともと自分のもってたサーバー環境をフルリニューアルする作業を正月にやっており、それをやったために作れたサイトだったりします。また、実際にはminioなどの設定周りは1日潰すぐらいハマって、相当大変でした。もうvirtual-hostやpathやsigned-urlとの食い合わせとか、cors周りとか見たくない・・・
 　ハッカソンが終わった後もぼちぼちGaussianSplattingの論文も読んだので、この辺から得られた知見も書いていきたいな。という気持ちがあります。そこそこGaussianSplattingに関する高画質化みたいな知見もたまりましたし。久々に熱中するような技術内容でした。

# 宣伝
株式会社STYLYではUnityエンジニア・サーバーサイドエンジニアを募集しています！！ご応募お待ちしています！！

https://www.wantedly.com/projects/1360135

https://www.wantedly.com/projects/1360123