【論文解説】Digging Into Self-Supervised Monocular Depth Estimation

【論文解説】Digging Into Self-Supervised Monocular Depth Estimation

# 概要

通称MonoDepth2と呼ばれる単眼深度推定モデルの論文を読んだので簡単に紹介します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4010/cc7d19db-6e4f-fc49-8653-e44ee463394c.png)

ベースとなる手法であるSfMLearnerについては、以下の記事で説明してみましたので、興味がありましたら御覧ください。

https://qiita.com/takoroy/items/191ec46211838daa47e1

本手法では大きく3つの改善を行っています。

- Per-Pixel Minimum Reprojection Loss：合成画像を構成するときに問題になるオクルージョンや画面外物体領域への対処
- Auto-Masking Stationary Pixels：フレーム間での変化が少なく、深度が無限大と推定されやすい領域への対処
- Full-res Multi-scale Estimation：低解像度の出力結果に穴（推定深度無限大）が生じやすいことへの対処

また、本論文の提案点以外に、本手法で使用されている別の論文によって提案された以下の2点についてもご紹介します。

- Depth Normalization：深度推定結果のスケールが曖昧になってしまう問題への対処。
- SSIM：L1距離に代わる、合成画像とターゲット画像からの損失計算方法。

# Per-Pixel Minimum Reprojection Loss
ソース画像からターゲット画像風の合成画像を構築する際に問題になるケースの代表的なものは、オクルージョンや画面外領域の問題によって、ターゲット画像中にしか映っていない物体や領域が存在する、というケースです。これは、ステレオカメラでも生じる問題です。

このような問題が生じているのにも関わらずターゲット画像と合成画像を比較して損失を計算してしまうのは、大きなノイズとなってしまう可能性があります。

本手法では、「複数のソース画像でよってたかって合成する」ことによって上記の課題をできるだけ解決します。単眼深度推定モデルの訓練では、ソース画像とターゲット画像の組をいくつか作るために、動画中の隣接する数フレームを組として取り扱います。このとき、1枚のターゲット画像に対して、残りをすべてソース画像として扱い、それぞれで合成画像を作ります。その後、最もターゲット画像に近い領域を各合成画像の一部から選択的に使用し、最終的な合成画像を構成します。

それを表しているのが以下の図です。この例では、ステレオカメラで撮影された左画像をターゲットとし、ソースとして右画像（黄）、左画像の1フレーム前（紫）、左画像の1フレーム後（緑）を使用しています。

下図の上真ん中にあるカラフルな画像は、どの画像をソースとして合成した領域としたら、最もターゲット画像に近い合成画像ができるか、を表しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4010/8b82d897-e776-8c83-b9e1-8c1eaa5d1385.png)

この操作は、数式的には以下の式で表されます。

$L\_{p}=\min \_{t^{\prime}} \operatorname{pe}\left(I\_{t}, I\_{t^{\prime} \rightarrow t}\right)$

$L\_{p}$は、ターゲット画像のピクセル$p$における損失を表し、$pe$は、photometric errorの略で、ターゲット画像$I\_{t}$と合成画像$I\_{t^{\prime} \rightarrow t}$との差異によって生じる損失を表します。あるピクセル$p$における損失は、いくつかのソース$t^{\prime}$のうち、photometric errorが最も小さいソースが選択される、ということを示しています。

# Auto-Masking Stationary Pixels

動くカメラと同じ動きをしている物体や低テクスチャの領域は、フレーム間での変化がないため、深度が無限大と推定されてしまいます。例として、道路のアスファルトのような同一のテクスチャが広がっている領域、概ね同じ速度で並走している車、などが挙げられます。

本手法では、単純に、前後のフレームでほとんど変化していない領域に関しては損失を計算しないよう、マスクする方法を採用しています。

下図が実際のマスク例です。左側の画像に対して、損失の対象としないマスク領域が0になった結果が右側に示されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4010/d9026a83-5fef-297f-cd15-7c8502f78985.png)

上側の画像では、平坦な色の空の領域や真っ白な車線、並走している車の領域がマスクされています。また、下側の画像では、カメラがほぼ静止しているフレームなので、ほとんどの領域がマスクされています。

数式的には、マスクは以下のように計算されます。$\left[\cdot\right]$は、中の条件式が真なら1、そうでなければ0とする操作です。

$\mu=\left[\min \_{t^{\prime}} p e\left(I\_{t}, I\_{t^{\prime} \rightarrow t}\right)<\min \_{t^{\prime}} p e\left(I\_{t}, I\_{t^{\prime}}\right)\right]$

$\min \_{t^{\prime}} p e\left(I\_{t}, I\_{t^{\prime}}\right)$は、ターゲット画像とソース画像の組を直接比較したときの差異を表します。この差異がほとんど無いときに、$\mu$が0になりやすくなります。

# Full-res Multi-scale Estimation

SfMLearnerでは、複数の解像度の深度マップを推定し、それぞれに対応する解像度のソース画像を元に、合成画像を作ることを試み、そこから損失を算出していました。
このように、まずは低解像度の深度マップを推定し、徐々に高解像度にしていき最終的な深度マップを得るというやり方は、深度マップ推定が局所解に陥ることを防ぐという効果があります。

しかし一方で、低解像度のソース画像、深度マップを用いて合成画像を生成し、低解像度のターゲット画像と比較する、という処理は、低解像度画像におけるテクスチャの不足によって、photometric errorが過小評価されてしまうことがあります。そして、この失敗によって、その領域の深度が無限大として推定されてしまうことがあります。

この問題を避けるため、本手法では、低解像度の深度マップを拡大し、高解像度にした上で、高解像度のソース画像・ターゲット画像を用いてphotometric errorを算出することにしています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4010/5af6dd44-144a-4006-be48-f06751ddba92.png)


# Depth Normalization

Depth Normalizationは、Wang, Chaoyang, et al.[^1]で提案された手法です。

単眼動画を使った深度推定においては、ターゲット画像からの深度推定と、ターゲット-ソース間のカメラ姿勢推定において、スケールが曖昧になるという問題があります。

それに対して、Wang, Chaoyang, et al.[^1]では、スケールに対する正規化手法を提案しています。

[^1]: Wang, Chaoyang, et al. "Learning depth from monocular videos using direct methods." Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition. 2018.

ステレオカメラを元に深度を推定する場合は、カメラ間の姿勢は固定であるためスケールが一意に定まりますが、単眼動画の異なるフレームから推定された深度と姿勢は、深度のスケールに応じて姿勢のスケールも変化させると、全く同じ別視点からの合成結果が得られてしまいます。

数式で確認してみましょう。ターゲット画像中のピクセル座標とソース画像中のピクセル座標の対応関係を表す式をSfMLearnerの論文から引いてみると、以下のようなものになっています。

$p_{s} \sim K \hat{T}\_{t \rightarrow s} \hat{D}\_{t}\left(p\_{t}\right) K^{-1} p\_{t}$

$p_t$がターゲット画像のピクセル、$p_s$がソース画像のピクセルです。

この式において、$\hat{T}\_{t \rightarrow s} \hat{D}\_t(p_t)$ の部分は、同じ計算結果となる異なるスケールを持つ深度に対応する$\tilde{T}\_{t \rightarrow s} \tilde{D}\_{t}\left(p\_{t}\right)$をいくらでも作ることができます。

そういうわけで、何らかの形で推定深度の正規化を行い、スケールが曖昧にならないようにする必要があります。本論文では、以下のようにターゲット画像とソース画像から推定された深度を元に深度の平均値を出し、それで深度を割っています。こうすれば、最終的な推定深度が極端に大きくなることはありません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4010/02781f42-e78c-ca8e-8fd7-8cd25edfcb2e.png)


以下は、この正規化を行わない場合、つまりSfMLearnerを使用した場合と、正規化を行った場合の、訓練中の推定深度の逆数の平均値がどのように推移するのかを示しています。正規化を行わない場合は、13エポック付近で急に0に近づいています。これは、深度推定結果のスケールが極端に大きくなってしまったことを表しています。実際、15エポック目の推定深度（の逆数）マップは、1色に塗りつぶされています。一方、正規化を行う場合は、ある程度のところで深度の逆数はとどまっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4010/433ff585-37ea-546d-2708-a91c4dff4b16.png)

このように、正規化によって深度や姿勢に残る曖昧さがもたらす弊害を抑制することができます。

# SSIM(Structural SIMilarity)

合成画像とターゲット画像の比較を行う場合に、SfMLearnerではL1損失を適用していました。しかし、画像と画像の比較を行う指標には様々なものがあります。

SSIMは、もともと画像の劣化を定量的に評価するための一般的な指標です。画像中のパッチ領域に関する同一性を評価することで算出されます。ターゲット画像と合成画像を、個々のピクセル単位で比較するよりは、ある程度大きな領域単位で比較したほうが良い結果になりそうというのは、よく分かる話です。

パッチ領域$x$と$y$について、その内部の平均$\mu_x, \mu_y$、その内部の分散${\sigma_x}^2, {\sigma_y}^2$、パッチ間の共分散$\sigma_{xy}$、分母が極端に小さい値にならないようにするための項$c_1, c_2$を使って算出します。

$\operatorname{SSIM}(x, y)=\frac{\left(2 \mu_{x} \mu_{y}+c_{1}\right)\left(2 \sigma_{x y}+c_{2}\right)}{\left(\mu_{x}^{2}+\mu_{y}^{2}+c_{1}\right)\left(\sigma_{x}^{2}+\sigma_{y}^{2}+c_{2}\right)}$

$c_1, c_2$は、$c_1 = (k_1 L)^2, c_2 = (k_2 L)^2$によって算出され、$L$はダイナミックレンジ（8bit画像なら、$256-1$）、$k1, k2$はデフォルトでは$k1=0.01, k2=0.03$です。

このあたりの数式は、[wikipedia](https://en.wikipedia.org/wiki/Structural_similarity#Algorithm)を参照しました。

# まとめ
MonoDepth2の論文で提案された3点と、別の論文から参照されていた2点について紹介しました。

オクルージョンや画面外領域の問題や、テクスチャが粗い領域の深度推定が無限遠になりがちな問題にも対処できるという点で、SfMLearnerの問題をうまく解決しているように見えます。深度推定マップを見ると、明らかにくっきりとした結果になっていて、これ以上何かやることあるのか？　という気もしてきます。

しかし、本手法でも「動くカメラと静止した物体」という前提は保たれたままです。次はこの問題に対処した手法を提案した論文を見てきましょう。