Windows10でTensorflow+Kerasを使って物体検出（SSD）のデモをする

　インターネットで公開されている情報を見ると簡単そうだったので手を出してみたけど、意外にハマったので、とりあえず、うまくいったパターンを書き残しました。

# OS選び

　当初、Ubuntu Linux16を使ってましたが、動画の物体検出の時に、python-opencvでMP4やAVI等の動画フォーマットを扱う術にたどり着けず、紆余曲折の末、Windows10になりました。OpenCVをソースからコンパイルしてインストールするところまではいけたのですが、pythonからの利用方法が分からなかった．．．orz


# インストール方法

## Anacondaインストーラのダウンロード
[Download Anaconda Now! | Continuum](https://www.continuum.io/downloads)からanacondaのインストーラをダウンロードします。


## インストーラを実行

「Install for:」はrecommendedの通り「Just Me」が無難です。「All Users」でインストールすると、コマンドによっては管理者権限で実行しないと、いろいろと面倒なことになったりすることが、たまに、あります。


## python3.5環境の作成

　2017年6月現在、WindowsでTensorflowを動かすためにはPython3.5である必要があるそうです。なので、スタートメニューから「Anaconda Prompt」を起動し、下記のコマンドを実行し、Python3.5環境を作成します。

```cmd:
> conda create --name=python35 python=3.5 jupyter
```

### Jupyter notebookへの登録

　コマンドプロンプトでいろいろする場合は必要ないですが、Jupyter notebookを使う場合は必要です。

```cmd:
> activate python35
> ipython kernel install --user --name=python35 --display-name=python35
```


## Tensorflowのインストール

```cmd:
> pip install --upgrade tensorflow
```


## Kerasのインストール

### Numpyの更新

[Python Extension Packages for Windows - Christoph Gohlke](http://www.lfd.uci.edu/~gohlke/pythonlibs/#numpy)からNumpy+MKLのwhlファイルをダウンロードし、それをインストールします。

```cmd:Windows10_64bit
> pip install --upgrade "numpy-1.13.0+mkl-cp35-cp35m-win_amd64.whl"
```


### Scipyの更新

[Python Extension Packages for Windows - Christoph Gohlke](http://www.lfd.uci.edu/~gohlke/pythonlibs/#scipy)から最新のScipyのwhlファイルをダウンロードし、それをインストールします。

```cmd:Windows10_64bit
> pip install --upgrade scipy-0.19.0-cp35-cp35m-win_amd64.whl
```


### Kerasのインストール

```cmd:
> pip install --upgrade keras==1.2.2
```

　バージョンを指定しないと2系のKerasがインストールされますが、実行時にいろいろエラーが吐かれ、その道の人じゃないと対応でき無さそうなので、バージョン1.2.2のKerasをインストールします。


### その他のライブラリのインストール

```cmd:
> pip install --upgrade opencv-python pillow matplotlib h5py
```

- opencv-python<br />OpenCVのpythonライブラリ
- pillow<br />画像処理ライブラリ
- matplotlib<br />グラフ描画ライブラリ。画像認識結果の出力に使用される。
- h5py<br />HDF5ファイルを扱うためのライブラリ。Kerasのweightsファイルを読み込むときに使用する（らしい）。


## SSD_Keras

### GITリポジトリの取得

　SSDをKerasで実装したソース一式がGitHubで公開されているので、それを使用させてもらいます。

```cmd:
> git clone https://github.com/rykov8/ssd_keras.git
> cd ssd_keras
```

### 学習済みモデルのダウンロード

　[rykov8/ssd_keras](https://github.com/rykov8/ssd_keras)のREADME.mdに書かれていますが、[MEGA](https://mega.nz/#F!7RowVLCL!q3cEVRK9jyOSB9el3SssIA)からweights_SSD300.hdf5をダウンロードして、ssd_kerasのホームディレクトリにコピーします。


### SSD_Kerasの動作確認

#### 画像のSSD

　Jupyter notebookでSSD.ipynbを読込み、実行します。SSD.ipynbの下記のブロックを変更したり、追加したりすると、自前の画像を認識対象にすることができます。

```py3:SSD.ipynb
img_path = '自前の画像ファイルパス'
img = image.load_img(img_path, target_size=(300, 300))
img = image.img_to_array(img)
images.append(imread(img_path))
inputs.append(img.copy())
```


### 動画のSSD

　ssd_keras/testing_utilsに動画SSD用のスクリプトが格納されています。
　videotest_example.pyの下記のところに対象の動画ファイルのパスを指定します。

```py3:videotest_example.py
vid_test.run('ここに動画ファイルのパスを記述する')
```

#### 実行時のエラー対策

　OpenCVのバージョンの影響なのか、下記の変更をしないとエラー終了します。

```diff:videotest.py
diff --git a/testing_utils/videotest.py b/testing_utils/videotest.py
index 0cbae3c..06e6f4d 100644
--- a/testing_utils/videotest.py
+++ b/testing_utils/videotest.py
@@ -84,8 +84,8 @@ class VideoTest(object):
             "trying to open a webcam, make sure you video_path is an integer!"))

         # Compute aspect ratio of video
-        vidw = vid.get(cv2.cv.CV_CAP_PROP_FRAME_WIDTH)
-        vidh = vid.get(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT)
+        vidw = vid.get(cv2.CAP_PROP_FRAME_WIDTH)
+        vidh = vid.get(cv2.CAP_PROP_FRAME_HEIGHT)
         vidar = vidw/vidh

         # Skip frames until reaching start_frame

```


# 参考にさせて頂いたサイト

- [SSD: Single Shot MultiBox Detector 高速リアルタイム物体検出デモをKerasで試す](http://qiita.com/PonDad/items/6f9e6d9397951cadc6be)
- [windowsにkerasをインストールする](http://qiita.com/tmizu23/items/fd20a787b254d85ed009)