WindowsでYOLOのデモ

YOLO
===

YOLOとはリアルタイム物体検出アルゴリズムで、「You only look once」の頭文字を取って「YOLO」と呼ばれています。
YOLOはDarknetというフレームワークで開発されています。
アルゴリズムの詳細は論文を検索してみてください。

- [【論文紹介】YOLOの論文を読んだので要点をまとめてみた](https://dev.classmethod.jp/articles/research_paper_yolo/)


ビルド環境構築
===

## Visual Studio 2017

**C++によるデスクトップ開発** をインストールします。

![darknet_vs2017_cpp_develop.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117636/8c08cf72-b432-6999-54dd-b524c60d5cea.png)


## CUDA Toolkit／cuDNN

下記バージョンの CUDA Toolkit、cuDNNをインストールします。
インストール方法につていは「CUDA Toolkit」あたりで検索すると解説サイトがヒットすると思います。
【参考】[NVIDIA CUDA toolkit on Windows](https://qiita.com/n-yamanaka/items/b00a94eec7eac4d2e76a) 

- CUDA Toolkit 10.1
- cuDNN 7.4


## OpenCV

[OpenCV](https://opencv.org/) からビルド済みの OpenCV をダウンロードします。
2020年7月現在、最新版は 4.x.x ですが 3.4.x を入手します。
Windows版は自己解凍型の実行ファイルで配布されていますので、入手後、とりあえず下記のフォルダに展開します。 

```
C:\tools\opencv
```

で、下記フォルダパスを環境変数 Path に登録しておきます。

```
C:\tools\opencv\build\x64\vc14\bin
```


Darknetのビルド
===

1. ソースコードの入手
  [AlexeyAB/darknet](https://github.com/AlexeyAB/darknet) から Darknet のソースコード一式を入手します。
  下記の手順は **C:\work** にGitリポジトリを clone したことを前提としています。

    ```cmd
    > cd C:\work
    > git clone https://github.com/AlexeyAB/darknet.git
    ```

2. Visual Studio 2017の起動
  darknet.sln（c:\work\darknet\build\darknet\darknet.sln）をVS2017 プロジェクトを開きます。

3. プロジェクトの設定
  - ビルドの依存関係設定
      - プロジェクトを右クリック ⇒ ビルドの依存関係 ⇒ ビルドのカスタマイズ を開きます。
      - CUDA 10.1にチェックを入れ、「OK」ボタンを押下します。
        ![darknet_vs2017_build_dependence.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117636/043b8061-2f82-9706-fe9f-b2ef8255b7e0.png)
   - 構成とプラットフォームの変更
     - メニューから ビルド ⇒ 構成マネージャー を開きます。
        - 構成・プラットフォームで下記を選択します。
          - 構成：Release
          - プラットフォーム： x64
          ![darknet_vs2017_build_構成マネージャ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117636/6ca330ed-cde2-fe48-8f8d-80a9a74ef9a2.png)
    - インクルードディレクトリの設定
      - プロジェクトを右クリック ⇒ プロパティ を開きます。
      - 「C/C++」→「全般」→「追加のインクルードディレクトリ」で以下を追加します。
          - C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.1\bin
          - C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.1\include
          - C:\tools\cuda\include
          - C:\tools\opencv\build\include
    - ライブラリディレクトリの設定
      - プロジェクトを右クリック ⇒ プロパティ を開きます。
      - 「リンカー」→「全般」→「追加のライブラリディレクトリ」で以下を追加します。
          - C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.1\lib
          - C:\tools\cuda\lib\x64
          - C:\tools\opencv\build\x64\vc14\lib

上記設定後、ビルドを実行すると、**C:\work\darknet\build\darknet\x64** にdarknet.exeが生成されます。


darknet.exeの使い方
===

darknet.exe を使用するためには YOLO のバージョンに対応した weights ファイルを入手する必要があります。
主なファイルは下記のリンク先ファイルになります。

- [yolov3.weights](https://pjreddie.com/media/files/yolov3.weights) (237 MB)
- [yolov3-tiny.weights](https://pjreddie.com/media/files/yolov3-tiny.weights) (33.7 MB)

- [yolov4.weights](https://github.com/AlexeyAB/darknet/releases/download/darknet_yolo_v3_optimal/yolov4.weights) (245 MB)
- [yolov4-tiny.weights](https://github.com/AlexeyAB/darknet/releases/download/darknet_yolo_v4_pre/yolov4-tiny.weights) (23.1 MB)


## 画像ファイルに映る物体の検出

darknet のソースの中にサンプルの写真が何枚か入っていますので、それを利用して動作確認ができます。

- YOLO v3の場合

    ```cmd
    > darknet detector test cfg/coco.data cfg/yolov3.cfg yolov3.weights data/dog.jpg
    ```

    ![darknet_yolov3_dog.jpg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117636/3c0cf617-170b-0dd9-f120-f9e063af180b.png)

- YOLO v4の場合

    ```cmd
    > darknet detector test cfg/coco.data cfg/yolov4.cfg yolov4.weights data/dog.jpg
    ```

    ![darknet_yolov4_dog.jpg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117636/c9aa66d1-6ada-c6ad-2f29-8f4ff14edb90.png)
    車の前方にあるゴミ捨て？はpottedplant（鉢植）に見えなくもない？


## カメラに映る映像のリアルタイム物体検出

PCにカメラを付けると、カメラの映像を入力にして物体検出をしてくれます。
GPU無しで実行するのは結構きついです。
ちなみに、GeForce 1050では 約7フレーム/秒 くらいでした。

  ```cmd
  > darknet detector demo cfg/coco.data cfg/yolov4.cfg yolov4.weights
  ```


## MP4動画映像のリアルタイム物体検出

  ```cmd
  > darknet detector demo cfg/coco.data cfg/yolov4.cfg yolov4.weights -thresh 0.5 data/test.mp4 -dont_show 1 -out_filename result/test_out.mp4
  ```


参考サイト
===

- [Darknet: Open Source Neural Networks in C](https://pjreddie.com/darknet/)
- [YOLO: Real-Time Object Detection](https://pjreddie.com/darknet/yolo/)
- [Windows環境でYOLO](https://qiita.com/tizonaColada_99/items/74069885bf6d8a56ad63)
- [Windows 10上のDarknetでYolo v3をトレーニングしOpenCVから使ってみる - にせねこメモ](https://nixeneko.hatenablog.com/entry/2018/08/15/000000)