はじめに
3D Gaussian Splatting(3DGS)は3Dシーンの再構成で一気に広まりましたが、その考え方を 1枚の2D画像の表現と圧縮 に持ち込んだのが今回紹介する GaussianImage です。
- 論文:Xinjie Zhang, Xingtong Ge ほか「GaussianImage: 1000 FPS Image Representation and Compression by 2D Gaussian Splatting」(ECCV 2024)
- arXiv:https://arxiv.org/abs/2403.08551 (CC BY 4.0)
- コード:https://github.com/Xinjie-Q/GaussianImage
この記事では、論文の要点に加えて、読んでいて引っかかりやすい「深度ソートはなぜ要らないのか」「奥行きや反射は大丈夫なのか」といった疑問も整理します。
3行まとめ
- 画像を数万個の 2D平面上のガウシアン(1個あたり8パラメータ)の重ね合わせで表す
- 3DGSの「深度ソート+α-blending」を ただの重み付き和 に置き換え、ソート不要で高速化
- 量子化を組み合わせて画像コーデックにし、約2000 FPSでデコード(圧縮率はCOIN/COIN++と同程度)
背景:INRの弱点
画像を「座標 → 色」の関数としてニューラルネットで表す 陰関数ニューラル表現(INR)(SIREN、WIRE、Instant-NGPなど)は、画像表現や圧縮で成果を上げてきました。ただし、
- 大きなMLPを使うと学習もデコードも遅い
- ハッシュグリッド系(I-NGPなど)は速いが、GPUメモリを大量に使う
という弱点があり、ローエンド機器での利用が難しい状況でした。そこで「明示的な表現で、ラスタライズで速く描ける」3DGSの仕組みを画像に使おう、というのが出発点です。
3DGSをそのまま使うと何が困るか
論文は、3DGSを1枚の画像に素直に適用する場合の問題を2つ挙げています。
- パラメータが重すぎる:3Dガウシアンは1個あたり59パラメータ(SH係数を含む)。数十KBの画像を表すのに数十MBになってしまう。
- 深度ソートができない:3DGSのα-blendingはカメラから見た深度順にガウシアンを並べる必要があるが、1枚の画像にはカメラパラメータも深度もない(スクリーンショットやAI生成画像はそもそも撮影されていない)。
GaussianImageの仕組み
2Dガウシアン(8パラメータ)
各ガウシアンは画像平面上に置かれ、以下で表されます。
| 属性 | 次元 | 備考 |
|---|---|---|
| 位置 $\mu$ | 2 | tanhで (−1, 1) に制限 |
| 共分散 $\Sigma$ | 3 | コレスキー分解 $\Sigma = LL^T$ の下三角要素 $l_1, l_2, l_3$ |
| 重み付き色 $c'$ | 3 | 色と不透明度を統合したもの |
共分散は半正定値でなければならないので、直接学習せずに分解形(コレスキー分解、または3DGSと同じ回転×スケール)を学習します。どちらでも表現力はほぼ同じですが、量子化して圧縮するときはコレスキー分解の方が頑健だったそうです。
3DGSにあった射影変換・SH・不透明度は不要になり、59 → 8パラメータ(7.375倍の削減) です。
ソート不要の「累積和」ラスタライズ
3DGSでは、ピクセル $i$ の色をこう計算します。
$$
C_i = \sum_{n} c_n , \alpha_n , T_n, \quad T_n = \prod_{m=1}^{n-1}(1-\alpha_m)
$$
$T_n$(累積透過率)は「手前のガウシアンをすり抜けて光が届く割合」で、手前から順に計算するので 順番に依存 します。
GaussianImageではこれを単純な重み付き和に置き換えます。
$$
C_i = \sum_{n} c'_n \exp(-\sigma_n), \quad \sigma_n = \frac{1}{2} d_n^T \Sigma_n^{-1} d_n
$$
足し算なので順番は関係なく、ソートが不要 になります。累積不透明度による打ち切りもしないので、ピクセルを覆う全ガウシアンがフィットに使われます。
そもそも3DGSはなぜ順番に描くのか
3DGSで深度順のα-blendingが必要なのは 遮蔽(手前の物が奥を隠す) を表すためです。これはNeRFのボリュームレンダリング方程式を離散化したもので、視点が変わるたびに前後関係が入れ替わるので、毎回ソートし直します。
一方GaussianImageは視点が1つに固定なので、各ガウシアンがピクセルに与える最終的な寄与を 最初から学習パラメータとして持てばよい、という発想です。
論文では「$T_n$ を不透明度に統合した」と説明されていますが、$T_n$ はピクセルごとに異なる値なので、厳密に同値な変形ではありません。「遮蔽のモデルを捨てて、単純な重ね合わせに置き換えた」と理解するのが正確だと思います。そのため $c'$ は [0, 1] に収まらず、物理的な色というより「足し合わせて正しい色になるための重み」です。
学習
- 損失はL2のみ(L1やSSIMを混ぜるより良かった)
- 3DGSの適応的密度制御(分割・複製)は使わない。2D画像には「何もない空間」がないため
- Adanオプティマイザで50,000ステップ、V100で1枚あたり約2分
画像コーデックにする
ここでいう 画像コーデック は、JPEGのように「画像を小さなビット列にして、そこから復元する仕組み一式」のことです。画像そのものの代わりに「その画像を描けるガウシアンのパラメータ」を保存します。
エンコード
- 画像にガウシアンをフィットさせる(オーバーフィッティング)
- 属性ごとに量子化し、その状態でファインチューニング
- 位置:FP16(量子化に敏感なため)
- 共分散:6ビット整数(学習可能なスケール・オフセット付き)
- 色:残差ベクトル量子化(RVQ、コードブックサイズ8 × 2段)
- (任意)部分ビットバック符号化でさらに削る
デコード
- 量子化値を元のスケールに戻す
- 累積和ラスタライズで描画
部分ビットバック符号化は、「ガウシアンの並び順には意味がない(N! 通りの並びが同値)」ことを利用して、その分のビットを節約する手法です。ただし処理が遅いので、論文でも「到達可能な上限を示す概念実証」という位置づけです。
結果
画像表現(Kodak、768×512 × 24枚)
| 手法 | PSNR | 学習時間 | FPS | GPUメモリ | パラメータ |
|---|---|---|---|---|---|
| WIRE | 41.47 | 約4時間 | 11 | 2619 MiB | 137K |
| SIREN | 40.83 | 約1.8時間 | 29 | 1809 MiB | 273K |
| I-NGP | 43.88 | 491 s | 1297 | 1525 MiB | 300K |
| 3D GS | 43.69 | 340 s | 859 | 557 MiB | 3540K |
| GaussianImage | 44.08 | 107 s | 2092 | 419 MiB | 560K |
画質は同等以上のまま、学習・描画速度とGPUメモリで優位です。
画像圧縮(DIV2K、低bpp時)
| 手法 | bpp | PSNR | エンコードFPS | デコードFPS |
|---|---|---|---|---|
| JPEG | 0.32 | 25.29 | 609 | 615 |
| Ballé18(VAE) | 0.25 | 28.75 | 16.5 | 15.9 |
| COIN(INR) | 0.34 | 25.80 | 0.0005 | 166 |
| GaussianImage | 0.32 | 25.66 | 0.004 | 1971 |
- レート歪み性能はCOIN/COIN++と同程度で、ビットバック符号化を使うと上回る
- MS-SSIMではCOINを大きく上回る
- デコードはJPEGより速い
一方で、JPEG2000やVAE系(Ballé)には圧縮性能で明確に負けています。またエンコードは画像ごとに学習するので非常に遅く、エンコードとデコードの速さが極端に非対称です。
アブレーション(Kodak、30,000ガウシアン)
| 変更 | PSNR | パラメータ |
|---|---|---|
| 3D GS(L2損失) | 37.41 | 1770K |
| 2Dガウシアンに変更 | 37.89 | 270K |
| +累積和ラスタライズ | 38.69(+0.8 dB) | 270K |
| +色と不透明度を統合 | 38.57 | 240K |
ソートをやめて和にしたことで、速くなるだけでなく画質も上がっているのが面白い点です。
よくある疑問
2D画像を2Dガウシアンで表して、2Dで出力する?
はい。入力も出力も1枚の画像で、3D空間やカメラは一切出てきません。
| 3DGS | GaussianImage | |
|---|---|---|
| 入力 | 多視点画像+カメラ姿勢 | 画像1枚 |
| ガウシアンの場所 | 3D空間 | 画像平面 |
| パラメータ数 | 59 | 8 |
| 描画 | 射影 → ソート → α-blending | 重み付き和 |
| 出力 | 新しい視点の画像 | 元画像の再現 |
名前が似ている 2DGS(Huang et al., SIGGRAPH 2024)は別物です。2DGSは「平たい円盤状のガウシアンを3D空間に置く」3D再構成手法で、GaussianImageは「2D平面にガウシアンを置く」画像表現手法です。
奥行きがないと、きれいに描けないのでは?
描画される画像としては問題ありません。写真に写っている遠近感や物体の境界は、撮影された時点で2Dの色の並びになっているからです。GaussianImageは前後関係を計算せず、境界を「急に色が変わるエッジ」として細長いガウシアンで再現します。
「ランダム」と書かれているのは 初期配置 と メモリ上の並び順 のことで、位置は最適化で動きますし、和なので並び順は結果に影響しません。
ただし、奥行きがないので 視点を動かす・手前の物体だけ動かす といったことはできません。
鏡や水の反射は?
これも問題になりません。視点が固定なので、反射は単なる模様としてフィットされます。むしろ反射は 3DGSの方が苦手 で、視点依存の見え方を低次のSHで表しきれず、鏡の奥に偽のガウシアンを作ってしまうことがあります。GaussianImageはSHを捨てているので、この問題自体がありません。
難しいのは反射かどうかより、細かい波紋のような 高周波の模様が多い領域 で、ガウシアン数が少ないとぼやけます。
まとめ・感想
- 3DGSから「3D」と「視点」に関わる部分を削ぎ落とした結果、8パラメータ・ソート不要の非常にシンプルな表現になっている
- デコードの速さとメモリの軽さは明確な強みで、圧縮率やエンコード速度は今後の課題(論文の考察でも、VAE系とはエンコード速度で4桁差があると認めています)
- 論文の今後の展望として、2Dガウシアンを単位にしたテキスト誘導編集や、分類・検出などの下流タスクへの利用が挙げられており、明示的な表現ならではの使い道が気になるところです
参考
- Zhang et al., "GaussianImage: 1000 FPS Image Representation and Compression by 2D Gaussian Splatting", arXiv:2403.08551(CC BY 4.0). 本記事の数値・図表の内容は同論文に基づきます
- Kerbl et al., "3D Gaussian Splatting for Real-Time Radiance Field Rendering", SIGGRAPH 2023
- Huang et al., "2D Gaussian Splatting for Geometrically Accurate Radiance Fields", SIGGRAPH 2024