単眼カメラの撮影画像に、学習済みの深度推定器を使ってみた（MacOS CPU）


__[@yakiimo121さんのウェブサイト「MiDaS Webcamを用いてリアルタイム単眼深度推定してみた」](https://qiita.com/yakiimo121/items/a86c01a39af56475c216)__を参考にして、GitHubに上がっている[論文 "Towards Robust Monocular Depth Estimation: Mixing Datasets for Zero-shot Cross-dataset Transfer"](https://arxiv.org/pdf/1907.01341.pdf)の実装コードを動かしてみました。

####__実行したコード__

- [github.com/intel-isl/MiDaS](https://github.com/intel-isl/MiDaS)

__最初に、実行結果の例を紹介します。__

１枚の入力画像（左側）に対して、2枚の画像（右側の上段と下段）が出力されます。

![スクリーンショット 2021-07-16 17.07.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1754134/f80beae1-cd19-9fe4-69df-c286ccd480ca.png)

####__（ 入力画像の入手元 ）　__

素材となるファイルは、ウェブサイトから、手動でダウンロードした建物や風景の画像ファイルを使いました。

![スクリーンショット 2021-07-16 16.45.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1754134/fa2d6ab3-b51a-81bd-a58a-62017528ced0.png)

####__計算環境__

Macbookに、先ほどの[GitHubリポジトリ](https://github.com/intel-isl/MiDaS)__から、スクリプト資源一式を__*git clone*__して、CPUだけを使って、推論を実行しました。

MacbookのTerminalでの実行記録を掲載します。
__*python3 run.py --model_type dpt_large*__と、叩くだけで成功しました。

__*"Towards Robust Monocular Depth Estimation*論文__では、単眼カメラで撮影した画像から、画像の奥行き（撮影者からの距離の遠近）を推定するアルゴリズムが提案されています。この技術は、「単眼度深度推定」と呼ばれています。

####__実行方法__

Terminalに打ち込んだコマンドは、以下です。
（環境構築については、この記事の最後に掲載しています）

__model_type__としては、 __*dpt_large*__を選びました。
これは、GitHubリポジトリから取得した4つの（学習済み）重みファイルの中で、最もきめ細かい解析が行えるモデルです。その代わり、取計算時間は4つの中で最長です。


```bash:Terminal
electron@diynoMacBook-Pro MiDaS % python3 run.py --model_type dpt_large
initialize
device: cpu
start processing
  processing input/cars.jpg (1/5)
/usr/local/lib/python3.9/site-packages/torch/nn/functional.py:3451: UserWarning: Default upsampling behavior when mode=bilinear is changed to align_corners=False since 0.4.0. Please specify align_corners=True if the old behavior is desired. See the documentation of nn.Upsample for details.
  warnings.warn(
  processing input/uk.jpeg (2/5)
  processing input/pic1.jpg (3/5)
  processing input/india.jpg (4/5)
  processing input/kyoto.jpg (5/5)
finished
electron@diynoMacBook-Pro MiDaS % 
```

###入力データと出力データ

####（ 入力画像 ）

入力画像は、撮影地点からの距離が、モノクロの明暗の単色で表現された画像に変換されます。

- 入力： 単眼カメラで撮影した画像ファイル
- 出力： 画像の奥行き（撮影者からの距離の遠近）が、モノクロの明暗で表現された画像

![スクリーンショット 2021-07-16 16.45.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1754134/fa2d6ab3-b51a-81bd-a58a-62017528ced0.png)

####（ 出力画像 ）

![スクリーンショット 2021-07-16 16.42.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1754134/c6e57c5a-322a-78ef-8eff-42dcc1fee533.png)


####何がすごいのか

従来、画像の深度を推定するためには、同一の対象風景（物体）を、2つのカメラ焦点から同時に捉える必要がありました。そのため、双眼鏡のような、2つのレンズを持ったカメラが必要でした。2つのレンズを持ったカメラは、「ステレオカメラ」と呼ばれています。


左右の目を持つ人間がやっているように、両焦点の間の視差を手掛かりに、見ている観察者と観察対象物との間の距離を推定していたためです。


![スクリーンショット 2021-07-16 21.28.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1754134/1c7f6af8-ca2f-5980-968a-5854785a61ca.png)
![スクリーンショット 2021-07-16 21.28.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1754134/e00efdd5-899c-356a-b6a3-44b807ada9ba.png)

- （ 参考 ）[Wikipedia ステレオカメラ](https://ja.wikipedia.org/wiki/%E3%82%B9%E3%83%86%E3%83%AC%E3%82%AA%E3%82%AB%E3%83%A1%E3%83%A9)

> ステレオカメラ（英: stereo camera）とは、対象物を複数の異なる方向から同時に撮影することにより、その奥行き方向の情報も記録できるようにしたカメラのことである。
>
> 通常は、1台で両眼視差を再現し、立体的な空間把握のできる立体写真の撮影が可能になっているものをさす。
>

- （ 参考 ）[ステレオカメラについて動画でご紹介！](https://www.zmp.co.jp/knowledge/adas_dev/adas_sensor/adas_camera/adas_stereo)

> ステレオカメラ(すてれおかめら、stereo camera)とは、人が物を見る原理と同じように、2つのカメラ(2眼のカメラ)を用いて対象物を複数の異なる方向から同時に撮影することにより、カメラの画素の位置情報から、奥行き方向の情報も計測することが可能なカメラのことです。
ステレオカメラはステレオビジョンやステレオカメラシステム、ステレオカメラユニット、ステレオデジタルカメラなどとも呼ばれることがあります。

今回動かしてみた実装コードは、レンズ（焦点）が１つしかない「1つ目」のカメラで撮影した画像に対して、被写体の距離深度を推定できるところが、技術的な達成点です。

「１つ目」の単眼カメラから、被写体との距離を明暗表示した画像を作り出せるようになると、低価格帯のドローンに内蔵されている（１つ目）カメラが捉えた画像を、リアルタイムに処理することができるなど、商業面でのニーズがありそうです。

- （ 参考 ）[東芝が単眼カメラのレンズ収差からステレオ並み高精度距離画像、深層学習で推定](https://xtech.nikkei.com/atcl/nxt/mag/rob/18/012600001/00047/)

> 普通の単眼カメラでわずか1枚の写真を撮るだけで、高精度な距離画像を得られる技術を東芝が開発した。
>
>　レンズの口径分による像のボケ具合や、レンズによる色収差・非点収差など画像上の像の微細な様子を基に距離を推定する方式であり、特殊なレンズや画像センサを使う必要がなく、通常の一般的な市販レンズをそのまま使える点が最大の特徴である（図1、図2）。
>
>　収差からの距離推定は非常に複雑なため、東芝は今回、ディープラーニング（深層学習）技術を用いることで、精度高く距離画像を得られるようにした。レンズを用いた事前の学習こそ必要だが、市販されている多くの単眼レンズとRGBカメラで手軽に距離画像を得られる。


####実行コード （ 全体 ）

inputディレクトリの中に、画像ファイルを5枚、置いておく

```bash:Terminal
electron@diynoMacBook-Pro MiDaS %
electron@diynoMacBook-Pro MiDaS % ls input 
cars.jpg	india.jpg	kyoto.jpg	pic1.jpg	uk.jpeg
electron@diynoMacBook-Pro MiDaS % 
```

実行前は、outputディレクりは空の状態

```bash:Terminal
electron@diynoMacBook-Pro MiDaS % ls output 
```

inputディレクトリに格納した複数の画像ファイルが、一括処理される。
（今回は5枚の画像ファイルを一括処理）

```bash:Terminal
electron@diynoMacBook-Pro MiDaS % python3 run.py --model_type dpt_large
initialize
device: cpu
start processing
  processing input/cars.jpg (1/5)
/usr/local/lib/python3.9/site-packages/torch/nn/functional.py:3451: UserWarning: Default upsampling behavior when mode=bilinear is changed to align_corners=False since 0.4.0. Please specify align_corners=True if the old behavior is desired. See the documentation of nn.Upsample for details.
  warnings.warn(
  processing input/uk.jpeg (2/5)
  processing input/pic1.jpg (3/5)
  processing input/india.jpg (4/5)
  processing input/kyoto.jpg (5/5)
finished
electron@diynoMacBook-Pro MiDaS % 
```

5枚の画像ファイルが出力された

```bash:Terminal
electron@diynoMacBook-Pro MiDaS % ls output 
cars.pfm	cars.png	india.pfm	india.png	kyoto.pfm	kyoto.png	pic1.pfm	pic1.png	uk.pfm		uk.png
electron@diynoMacBook-Pro MiDaS % 
```

###（ 環境構築 ）

- Python 3.7.4を使いました。

```bash:Terminal
electron@diynoMacBook-Pro ~ % mkdir opencv_midas 
electron@diynoMacBook-Pro ~ % cd opencv_midas 
electron@diynoMacBook-Pro opencv_midas % pyenv local 3.7.4
electron@diynoMacBook-Pro opencv_midas % pyenv versions     
  system
  2.7.16
  3.6.0
  3.6.1
  3.6.3
  3.6.3/envs/gpt2_ja
  3.7.0
* 3.7.4 (set by /Users/electron/opencv_midas/.python-version)
  3.9.0
  gpt2_ja
 electron@diynoMacBook-Pro opencv_midas %
 ``` 
 
 - 未取得だったので、pytorchとopencv-pythonモジュールを取得（pip install）
 
 ```bash:Terminal
electron@diynoMacBook-Pro opencv_midas % pip3 install torch==1.8.0 torchvision
electron@diynoMacBook-Pro opencv_midas % pip3 install opencv-python
```

```bash:Terminal
electron@diynoMacBook-Pro opencv_midas % git clone https://github.com/intel-isl/MiDaS.git

 ```bash:Terminal
electron@diynoMacBook-Pro opencv_midas % ls
MiDaS
electron@diynoMacBook-Pro opencv_midas % 
electron@diynoMacBook-Pro opencv_midas % ls MiDaS 
Dockerfile	README.md	input		mobile		ros		tf		weights
LICENSE		hubconf.py	midas		output		run.py		utils.py
electron@diynoMacBook-Pro opencv_midas % 
```

- デフォルトでは、__*weights*__ディレクトリの中は空。

 ```bash:Terminal
electron@diynoMacBook-Pro opencv_midas % ls MiDaS/weights 
electron@diynoMacBook-Pro opencv_midas %
```

- GitHubリポジトリから、各モデルの学習済みの重みパラメータファイルを取得（wget）

 ```bash:Terminal
electron@diynoMacBook-Pro opencv_midas % cd MiDaS 
electron@diynoMacBook-Pro MiDaS % wget https://github.com/intel-isl/DPT/releases/download/1_0/dpt_large-midas-2f21e586.pt
electron@diynoMacBook-Pro MiDaS % 
electron@diynoMacBook-Pro MiDaS % ls
Dockerfile			dpt_large-midas-2f21e586.pt	midas				ros				utils.py
LICENSE				hubconf.py			mobile				run.py				weights
README.md			input				output				tf
electron@diynoMacBook-Pro MiDaS % 
electron@diynoMacBook-Pro MiDaS % mv dpt_large-midas-2f21e586.pt ./weights/dpt_large-midas-2f21e586.pt
electron@diynoMacBook-Pro MiDaS % ls
Dockerfile	README.md	input		mobile		ros		tf		weights
LICENSE		hubconf.py	midas		output		run.py		utils.py
electron@diynoMacBook-Pro MiDaS % 
```

- 大中小それぞれのモデルの重みファイルを一つずつ取得（wget）

 ```bash:Terminal
electron@diynoMacBook-Pro MiDaS % cd weights 
electron@diynoMacBook-Pro weights % wget https://github.com/intel-isl/DPT/releases/download/1_0/dpt_hybrid-midas-501f0c75.pt
--2021-07-16 15:02:41--  https://github.com/intel-isl/DPT/releases/download/1_0/dpt_hybrid-midas-501f0c75.pt
・・・
electron@diynoMacBook-Pro weights % 
electron@diynoMacBook-Pro weights % ls
dpt_hybrid-midas-501f0c75.pt	dpt_large-midas-2f21e586.pt
electron@diynoMacBook-Pro weights % 
```

 ```bash:Terminal
electron@diynoMacBook-Pro weights % wget https://github.com/AlexeyAB/MiDaS/releases/download/midas_dpt/midas_v21_small-70d6b9c8.pt
・・・
2021-07-16 15:03:39 (15.4 MB/s) - `midas_v21_small-70d6b9c8.pt' へ保存完了 [85761505/85761505]

electron@diynoMacBook-Pro weights % 
```

 ```bash:Terminal
electron@diynoMacBook-Pro weights % wget https://github.com/AlexeyAB/MiDaS/releases/download/midas_dpt/midas_v21-f6b98070.pt
・・・
-2021-07-16 15:04:21 (12.7 MB/s) - `midas_v21-f6b98070.pt' へ保存完了 [422509849/422509849]

electron@diynoMacBook-Pro weights %
```

- 4種類のサイズ、各モデルの重みファイルが取得できた。

 ```bash:Terminal
electron@diynoMacBook-Pro weights % ls
dpt_hybrid-midas-501f0c75.pt	dpt_large-midas-2f21e586.pt	midas_v21-f6b98070.pt		midas_v21_small-70d6b9c8.pt
electron@diynoMacBook-Pro weights % 
```