Raspberry PiでDarknetを使う

# はじめに
本記事は、Raspberry PiでDarknetを使う方法について記載しています。

以前、[Pythonで作る簡単監視カメラ　Raspberry Pi + カメラモジュール + 焦電型赤外線センサー](https://qiita.com/Brutus/items/4c49cb66344109ad0161)を作りました。

今回、焦電型赤外線センサーで人体を検出時に、カメラモジュールで保存した画像ファイルに対して物体検出を行い、人間が検出された場合は通知する仕組みを作ろうと思いました。

結果的にDarknetを使えば、物体検出は簡単にできるのですが、本記事で使用しているRaspberry Pi 3 Model B+では、1回の物体検出で約5分程度かかるため、断念しました。。

備忘録的に、Darknetの使い方を簡潔にまとめます。

## Darknet
[Darknet](https://pjreddie.com/darknet/)（※）は、CおよびCUDAで記述されたオープンソースのニューラルネットワークフレームワークです。高速で簡単にインストールでき、CPUとGPUの計算をサポートしています。また、Darknetはオープンソースでパブリックドメインなため誰でも[無料](https://github.com/pjreddie/darknet/blob/master/LICENSE)に使用できます。Darknetを使用することで、学習済みのYOLOモデルが使えます。

Joseph Redmonという方が作成していて、[TED](https://www.ted.com/speakers/joseph_redmon)にも出ています。

- YouTube   
[Computers can see. Now what? | Joseph Redmon | TEDxGateway](https://www.youtube.com/watch?v=XS2UWYuh5u0)

（※）Darknetはプロジェクトの名前でもあります。

## YOLO
YOLOは、物体検出のアルゴリズムとして、１つのニューラルネットですべての検出を行うようにトレーニングされています。画像だけでなく映像もリアルタイムで処理できます。

>You Only Look Once（一度だけしか見ない）

YOLOの所以です。

現在の最新バージョンは、YOLO v3です。YOLO v2と比べてスピードより、精度向上が行なわれているのが特徴です。YOLO v3の詳細については、[YOLOv3: An Incremental Improvement](https://pjreddie.com/media/files/papers/YOLOv3.pdf)を参照。論文は[arXiv](https://arxiv.org/abs/1506.02640)より閲覧できます。

## 検証
Raspberry Pi 3 Model B+では、設定ファイルと分類重みファイルに**YOLO v3**を使用すると、Segmentation faultになるため、設定ファイルと分類重みファイルは**YOLO v2**を使用しています。

### Darknetのインストール
[Installing Darknet](https://pjreddie.com/darknet/install/)の通りに実施するだけなので、インストールは簡単です。必要に応じてオプションを選択します。本記事ではオプションを使用しません。

- gitからダウンロード   
`$ git clone https://github.com/pjreddie/darknet.git`
- ディレクトリを移動してmakeの実行   
`$ cd darknet/`   
`$ make`
- モデルのダウンロード（YOLO v2）（※）   
`$ wget https://pjreddie.com/media/files/yolov2.weights`

（※）files以下の分類重みファイル名を指定することで、その他の分類重みファイルもダウンロードできます。YOLO v3の場合は、以下のコマンドを実行します。

- モデルのダウンロード（YOLO v3）   
`$ wget https://pjreddie.com/media/files/yolov3.weights`

### Darknetの実行
Darknetコマンドの使い方は、`darknet`コマンドの引数にオプション指定します。yolov2を例に説明します。検出する場合は、`detector`、設定ファイルに`cfg/yolov2.cfg`、分類重みファイルに、`yolov2.weights`、検出を行うファイルはサンプルデータの`data/person.jpg`を指定しています。

- Darknetの実行   
`$ ./darknet detector test cfg/coco.data cfg/yolov2.cfg yolov2.weights data/person.jpg`

```console
layer     filters    size              input                output
    0 conv     32  3 x 3 / 1   608 x 608 x   3   ->   608 x 608 x  32  0.639 BFLOPs
    1 max          2 x 2 / 2   608 x 608 x  32   ->   304 x 304 x  32
    2 conv     64  3 x 3 / 1   304 x 304 x  32   ->   304 x 304 x  64  3.407 BFLOPs
    3 max          2 x 2 / 2   304 x 304 x  64   ->   152 x 152 x  64
    4 conv    128  3 x 3 / 1   152 x 152 x  64   ->   152 x 152 x 128  3.407 BFLOPs
    5 conv     64  1 x 1 / 1   152 x 152 x 128   ->   152 x 152 x  64  0.379 BFLOPs
    6 conv    128  3 x 3 / 1   152 x 152 x  64   ->   152 x 152 x 128  3.407 BFLOPs
    7 max          2 x 2 / 2   152 x 152 x 128   ->    76 x  76 x 128
    8 conv    256  3 x 3 / 1    76 x  76 x 128   ->    76 x  76 x 256  3.407 BFLOPs
    9 conv    128  1 x 1 / 1    76 x  76 x 256   ->    76 x  76 x 128  0.379 BFLOPs
   10 conv    256  3 x 3 / 1    76 x  76 x 128   ->    76 x  76 x 256  3.407 BFLOPs
   11 max          2 x 2 / 2    76 x  76 x 256   ->    38 x  38 x 256
   12 conv    512  3 x 3 / 1    38 x  38 x 256   ->    38 x  38 x 512  3.407 BFLOPs
   13 conv    256  1 x 1 / 1    38 x  38 x 512   ->    38 x  38 x 256  0.379 BFLOPs
   14 conv    512  3 x 3 / 1    38 x  38 x 256   ->    38 x  38 x 512  3.407 BFLOPs
   15 conv    256  1 x 1 / 1    38 x  38 x 512   ->    38 x  38 x 256  0.379 BFLOPs
   16 conv    512  3 x 3 / 1    38 x  38 x 256   ->    38 x  38 x 512  3.407 BFLOPs
   17 max          2 x 2 / 2    38 x  38 x 512   ->    19 x  19 x 512
   18 conv   1024  3 x 3 / 1    19 x  19 x 512   ->    19 x  19 x1024  3.407 BFLOPs
   19 conv    512  1 x 1 / 1    19 x  19 x1024   ->    19 x  19 x 512  0.379 BFLOPs
   20 conv   1024  3 x 3 / 1    19 x  19 x 512   ->    19 x  19 x1024  3.407 BFLOPs
   21 conv    512  1 x 1 / 1    19 x  19 x1024   ->    19 x  19 x 512  0.379 BFLOPs
   22 conv   1024  3 x 3 / 1    19 x  19 x 512   ->    19 x  19 x1024  3.407 BFLOPs
   23 conv   1024  3 x 3 / 1    19 x  19 x1024   ->    19 x  19 x1024  6.814 BFLOPs
   24 conv   1024  3 x 3 / 1    19 x  19 x1024   ->    19 x  19 x1024  6.814 BFLOPs
   25 route  16
   26 conv     64  1 x 1 / 1    38 x  38 x 512   ->    38 x  38 x  64  0.095 BFLOPs
   27 reorg              / 2    38 x  38 x  64   ->    19 x  19 x 256
   28 route  27 24
   29 conv   1024  3 x 3 / 1    19 x  19 x1280   ->    19 x  19 x1024  8.517 BFLOPs
   30 conv    425  1 x 1 / 1    19 x  19 x1024   ->    19 x  19 x 425  0.314 BFLOPs
   31 detection
mask_scale: Using default '1.000000'
Loading weights from yolov2.weights...Done!
data/person.jpg: Predicted in 299.373857 seconds.
horse: 82%
dog: 86%
person: 86%
```

上記コマンド実行後、 カレントディレクトリに「predictions.jpg」ファイルが生成されます。ファイルを参照すると物体検出が行なわれているのが確認できます。

![スクリーンショット 2019-09-16 17.35.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221759/056254ae-e0f7-5abe-6fd5-6c396887d92c.png)


# おわりに
Raspberry Pi 4 Model Bが今年の夏に発表されたので、今後に期待します。

日本では技適取得がまだのため、今のところ（本記事執筆時点）購入することができません。もしくは、Raspberry PiやLinuxなどでAI処理を行なうためのアクセラレータを使うという方法もあるかもしれませんが。。

何れにせよ、Darknetの様なフレームワークが、Raspberry Piの様な小型コンピュータで簡単に試せる時代はもう来ています。