TensorFlowでの物体検出が超手軽にできる「Object Detection Tools」をTensorFlow 2.xに対応しました

<img width="1072" alt="odt_02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81919/b1dccfc9-aa8f-75ef-04e9-195f2710705a.png">

素材提供：「[変デジ研究所](https://lab.hendigi.com/)」 ロンスタさん

# Object Detection APIがTensorFlow2.x対応
　全世界待望（？）のTensorFlowの物体検出ライブラリ「Object Detection API」がTensorFlow 2.x対応しました。

[TensorFlow 2 meets the Object Detection API](https://blog.tensorflow.org/2020/07/tensorflow-2-meets-object-detection-api.html)

　というわけで、このObject Detection APIを手軽に使える拙作のツール「Object Detection Tools」もTensorFlow 2.xに対応したスクリプトを早速作成して追加しました。

<a href="https://github.com/karaage0703/object_detection_tools"><img src="https://github-link-card.s3.ap-northeast-1.amazonaws.com/karaage0703/object_detection_tools.png" width="460px"></a>

　「Object Detection API」と「Object Detection Tools」に関しては、以下記事を参照下さい。

[TensorFlowの物体検出用ライブラリ「Object Detection API」を手軽に使えるソフト「Object Detection Tools」を作ってみた](https://karaage.hatenadiary.jp/entry/2019/05/27/073000)


　TensorFlow2.x対応したのは物体検出の推論部分だけで、Macでしか動作確認していませんが、LinuxやRaspberry Pi、Jetson Nanoでも動くと思います（そのうち確認します、誰か試して報告してくれたらとても嬉しいです）。WindowsもWSLでパスとかを工夫すれば動くのじゃ無いかなと期待しています。

　~~学習に関しては、まだTensorFlow2.xに対応していません。こっちを対応しろよという話かもしれませんが、多分やることはほとんど同じだと思いますので、とりあえず以下のTensorFlow1.xでの学習方法を参考にしてみてください。~~

　学習もTensorFlow 2.xに対応しました。以下のページを参照ください。

[「Object Detection API」で物体検出の自前データを学習する方法（TensorFlow 2.x版）](https://qiita.com/karaage0703/items/8567cc192e151bac3e50)

# 「Object Detection Tools」での物体検出スクリプトの使い方
  「Object Detection Tools」を使って、物体検出を手軽に実現する方法を書きたいと思います。「Object Detection API」は、公式のチュートリアルだと、色々事前準備が必要なのですが、こちらの方法だとTensorFlowとOpenCVさえあればサクッとリアルタイムの物体検出ができます。

## 環境構築
　MacとLinuxを想定しています。Apple Siliconの（M1 Mac）の場合は、セットアップ大きく変わるので、以下記事を参照ください。

https://zenn.dev/karaage0703/articles/0ab9e654cfb0ec

　これ以降は、以下Intel Macを想定したセットアップです。

- iMac(Retina 4K, 21.5-inch, 2017)
- 3.6GHz Intel Core i7
- メモリ 16GB
- macOS 10.13.6

　この記事では省略しますが、Linuxでもほぼ同じ要領でセットアップできます。以下は動作実績情報です。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Linux (GTX 1080, cuda 11.1, tf 2.4.1)で動きました。性能は、CenterNetで12 fps, EfficientDetで24fpsでした。tensorflow, cuda環境を新しくした後、ssdが全滅していたので、物体認識が動く環境が復活して助かりました！！</p>&mdash; Todotani (@todotani) <a href="https://twitter.com/todotani/status/1371024322572152832?ref_src=twsrc%5Etfw">March 14, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

　Python環境はPyenv + Anacondaを使ってセットアップしました。以下記事を参考にPyenvとAnacondaのインストールをします。

[pyenv/pyenv-virtualenv/Anacondaを使ってクリーンなPython環境をセットアップ](https://karaage.hatenadiary.jp/entry/2016/04/04/073000)



　続いて、以下コマンドを実行してPython環境を構築します。

```sh
$ pyenv install 3.7.3
$ pyenv virtualenv 3.7.3 od
$ pyenv global 3.7.3/envs/od
```

　続いて必要なライブラリのセットアップをします。

```sh
$ pip3 install tensorflow==2.3.0
$ pip3 install opencv-python
```

## 「Object Detection Tools」による物体検出
　最初にリポジトリをクローンします。

```sh
$ cd && git clone https://github.com/karaage0703/object_detection_tools
```

　TensorFlowで使用できる学習モデルのリンク先一覧は「Model Zoo」（モデルの動物園）と呼ばれ「Object Detection API」のリポジトリ内にあります。TensorFlow 1.x用とTensorFlow 2.x用があります。

[TensorFlow 1 Detection Model Zoo](https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/tf1_detection_zoo.md)

[TensorFlow 2 Detection Model Zoo](https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/tf2_detection_zoo.md)

　もちろん、今回はTensorFlow 2.x用の「Model Zoo」を使います。「Object Detection Tools」には、ダウンロードのスクリプトも用意していあります。今回は、CenterNetとEfficientDetを使ってみます。

### CenterNet
　まずは、CenterNetを試してみます。以下コマンドを実行して、モデルをダウンロードします。

```sh
$ cd ~/object_detection_tools/models
$ ./get_centernet_hg104_512x512_coco17_tpu-8.sh
```

　TensorFlow 1.xでは、学習済みのモデルはFreezeGraph形式（多くが`frozen_inference_graph.pb`という名前で保存されています）が使われていました。しかし、FreezeGraph形式は、TensorFlow2.xでは非推奨となりsaved model形式（多くが`saved_model.pb`という名前で保存されています）が使われるようになっています。拡張子が同じ`.pb`なので違いが分かりにくいですが、中身のフォーマットは異なるので注意が必要です。この辺りは、詳細は割愛しますが、以下のGoogle ColabのNotebookをみると多少理解が深まるかもしれません。

[inference_from_saved_model.ipynb](https://colab.research.google.com/drive/15LOxJ6rbpyKz-LQPEZ_eThoe1h4nwiJD?usp=sharing)

　続いて、CenterNetの学習済みのモデルを使って、物体検出のテストをします。PCにカメラがついている場合（Mac Book/iMac等）は、以下のコマンドを実行して下さい。もしカメラがなければ、適当なWebカメラでも大丈夫と思います。

　コマンドは以下となります。

```sh
$ cd ~/object_detection_tools
$ python3 scripts/object_detection_tf2.py -l='./models/coco-labels-paper.txt' -m='./models/centernet_hg104_512x512_coco17_tpu-8/saved_model/'
```

 上記のプログラムは`-l`のオプションでラベル、`-m`のオプションで使用するsaved_modelのあるディレクトリを指定します。実行するとカメラが起動して、以下のようにリアルタイムに物体検出の結果が表示されます。速度はPCに依存しますが、FPSは0.6程度と結構遅めです。

<img width="1072" alt="odt_01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81919/52dd28c2-8bea-7345-c9bf-b62ffbda98fd.png">
　静止画ですが、実際は動画です。

　ちなみに実行すると、大量の`with ops with custom gradients. Will likely fail if a gradient is requested.`というwarningが出ますが、この道の求道者である @PINTO さん曰く「無視して大丈夫です。」とのことなので、安心（？）して無視しましょう。

### EfficientDet
　他のモデルの場合も、同じ要領で簡単に試すことができます。次はEfficeintDetモデルで試して見ましょう。一番軽量なD0というモデルを試します。モデルのダウンロード方法は以下です。

```sh
$ cd ~/object_detection_tools/models
$ ./get_efficientdet_d0_coco17_tpu-32.sh
```

　続いて、物体検出のコマンドは以下です。

```sh
$ cd ~/object_detection_tools
$ python3 scripts/object_detection_tf2.py -l='./models/coco-labels-paper.txt' -m='./models/efficientdet_d0_coco17_tpu-32/saved_model/'
```

<img width="1072" alt="odt_02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81919/b1dccfc9-aa8f-75ef-04e9-195f2710705a.png">


　FPSは4程度と、CenterNetよりかなり高速ですね。

### その他のモデル
　その他のモデルも、同じ要領でモデルをダウンロードして使用することができます。スクリプトをみて「Model Zoo」のリンク先を確認すれば、すぐ真似て他のモデルも試すことができると思います。

## TIPS・機能
### ディープモザイク機能
　ウィンドウ上で`m`か`M`を押すと検出した物体がモザイクになります。元に戻したいときは`b`か`B`を押して下さい。

参考記事：[ディープラーニングで動画に自動でモザイクをかける「ディープモザイク」作ってみました](https://karaage.hatenadiary.jp/entry/2018/06/04/070000)

### 動画の物体検出
　カメラが無い場合は、動画も使用可能です。以下コマンドで動画のフリー素材をダウンロードしましょう。フリー素材は、有名ブログ「[変デジ研究所](https://lab.hendigi.com/)」のロンスタさんの提供です。

```
$ wget https://raw.githubusercontent.com/karaage0703/ssd_keras/master/free_data/lonestartx_free.mp4
```

　動画の場合は、以下のコマンドで物体検出が可能です。

```sh
$ cd ~/object_detection_tools
$ python3 scripts/object_detection_tf2.py -l='./models/coco-labels-paper.txt' -m='./models/centernet_hg104_512x512_coco17_tpu-8/saved_model/' -d='video' -i='./lonestartx_free.mp4'
```

　`-d`オプションでvideoを指定して、`-i`オプションでファイル名を指定できます。

## 「Object Detection Tools」でのエッジコンピューティング
　ラズパイ（Raspberry Pi）やJetson Nanoといった小型マイコンでの動作も想定しています。が、まだ動作確認できていません（すみません、そのうちやります）。一応、以下にセットアップ方法だけ書いておきます。

　TensorFlowとOpenCVさえセットアップすれば、基本的には上記方法と同じコマンドで動きます。

### Raspberry Piでのセットアップ
　ラズパイのディープラーニングのセットアップ方法は以下記事を参照ください。

[Raspberry Pi 4のディープラーニングで画像認識する環境をゼロから1時間で構築する方法](https://karaage.hatenadiary.jp/entry/rpi4-dl-setup)

　上記記事は、TensorFlow 1.xのセットアップしか書いてありませんが、TensorFlow 2.xは、@PINTO さんの「Tensorflow-bin」リポジトリを使えば簡単にセットアップできます。

[PINTO0309/Tensorflow-bin(GitHub)](https://github.com/PINTO0309/Tensorflow-bin)

　TensorFlow1.xをインストールした後であれば、以下を実行すれば、セットアップできます。

```sh
$ wget "https://raw.githubusercontent.com/PINTO0309/Tensorflow-bin/master/tensorflow-2.2.0-cp37-cp37m-linux_armv7l_download.sh"
$ ./tensorflow-2.2.0-cp37-cp37m-linux_armv7l_download.sh
$ sudo pip3 uninstall tensorflow
$ sudo -H pip3 install tensorflow-2.2.0-cp37-cp37m-linux_armv7l.whl
```

### Jetson Nano
　Jetson Nanoに関しては、以下記事を参照にセットアップください。

[Jetson NanoにJetPack 4.4を入れてTensorFlow・物体検出・姿勢推定・ROS2(Realsense)・ROS1動かしてみた](https://qiita.com/karaage0703/items/604ff6e0a8287aa0dce7)

## 「Object Detection API」のGoogle Colaboratoryのチュートリアル
　Google Colaboratory（Google Colab）で動く、良さそうなチュートリアルがあるのですが、リンク切れやConfigファイルの修正がされていない等、もろもろあってそのままでは動きません（何故…）。

　クリックすれば、推論までできるように修正したGoogle Colabのノートブックを公開します。興味ある人は参考にしてみてください。

[inference_tf2_colab.ipynb](https://colab.research.google.com/drive/1BD2iSuLGrHEEgpT7oxrO2JUeIKXZaysa?usp=sharing)
チェックポイント(ckpt）とObject Detection APIを使って画像の物体検出（推論）をするチュートリアルです。

[inference_from_saved_model.ipynb](https://colab.research.google.com/drive/15LOxJ6rbpyKz-LQPEZ_eThoe1h4nwiJD?usp=sharing)
saved modelを使って画像の物体検出（推論）をするチュートリアルです。Object Detection APIには依存せず、推論をしています。saved modelの理解を深めたい人は参考になるかもしれません。

　Google Colabに関しては、以下記事を参照ください。
[Google Colaboratoryを使えば環境構築不要・無料でPythonの機械学習ができて最高](https://karaage.hatenadiary.jp/entry/2018/03/21/073000)

# まとめ
　TensorFlow2.xに対応した「Object Detection Tools」で物体検出をする方法を簡単に紹介しました。多くのプラットフォームで簡単に学習済みの物体検出を試すことができますので興味ある方は活用してみてください。

　TensorFlow 2.x対応は、もっとゆっくりやっていこうと思ったのですが @PINTO さん @Kazuhito さんが秒速で「Object Detection API」に手を出し始めたので、刺激とアドバイスを受けつつ、駆け足で一気にやってしまいました。あくまでサンプルスクリプトなので、いい感じのクラス化とかは各自でお願いします。PRはいつでも大歓迎です。

　個人的には、公式にこういったスクリプトが用意されていなかったり、チュートリアルがまともに動かなかったりするのが謎ですが…私のような人が少しでも役に立てるチャンスと前向きに捉えたいと思います。

# 関連記事
[Raspberry Pi 4のディープラーニングで画像認識する環境をゼロから1時間で構築する方法](https://karaage.hatenadiary.jp/entry/rpi4-dl-setup)

[Jetson Nano関係のTIPSまとめ](https://qiita.com/karaage0703/items/b14c249aa33112669ee4)

[Jetson Nanoでリアルタイムに物体検出をする方法（TensorFlow Object Detection API/NVIDIA TensorRT）](https://qiita.com/karaage0703/items/67050f2418aa6bb3851a)

[TensorFlowの「Object Detection API」で物体検出の自前データを学習する方法](https://qiita.com/karaage0703/items/76ef6b774e3cd69028bb)

[Raspberry PiでPINTOさん謹製「TensorFlowLite-bin」を使ってお手軽に爆速エッジコンピューティング](https://qiita.com/karaage0703/items/38f314d01a67ded949c2)


# 参考リンク
https://leimao.github.io/blog/Save-Load-Inference-From-TF2-Frozen-Graph/

https://github.com/leimao/Frozen_Graph_TensorFlow/tree/master/TensorFlow_v2

https://www.tensorflow.org/tutorials/distribute/save_and_load

https://qiita.com/t_shimmura/items/1ebd2414310f827ed608

https://qiita.com/parkkiung123/items/13adb482860f356f97f3

https://www.tensorflow.org/guide/saved_model

# 変更履歴
- 2021/03/14 Apple Silicon MacとLinuxでのセットアップと動作に関して追記
- 2020/08/02 TensorFlow 2.xの学習に関して追記