MachineLearning
DeepLearning
Keras
TensorFlow

SSD(Keras / TensorFlow)でディープラーニングによる動画の物体検出を行う

やったこと

前回に引き続き、動画の物体検出を行いました。
今回はアルゴリズムを変えて、SSDという物体検出アルゴリズムを使用しています。

3.gif

(動画はPIXELS VIDEOSよりCCライセンスの動画を使用しました。)

SSD(Single Shot MultiBox Detector)とは

論文はこちら(2016年)

前回使用したYOLO(You only look once)アルゴリズムと同じく、畳み込みニューラルネットワーク(CNN:Convolutional Neural Network)を用いた物体検出アルゴリズムです。

他のシングルステージ方式と比較して、入力画像サイズが小さくてもSSDの精度ははるかに優れています。

Compared to other single stage methods, SSD has much better accuracy, even with a smaller input image size.

300×300入力の場合、58 FPSのVOC2007テストで72.1%mAP、500×500入力では75.1%mAPを達成。
同等の最速R-CNNモデルを凌駕しています。

For 300×300 input, SSD achieves 72.1% mAP on VOC2007 test at 58 FPS on a Nvidia Titan X and for 500×500 input, SSD achieves 75.1% mAP, outperforming a comparable state of the art Faster R-CNN model.

論文提出時のコードはCaffeで書かれています。

Code is available at: https://github.com/weiliu89/caffe/tree/ssd .

SSDを動かす

今回は、Keras/TensorFlowで実装されたソースを利用します。
サンプルで提供されている学習済重みデータには、Pascal VOC Challenges 2007年のデータを使用しているようです。

環境構築

今回使用するライブラリのバージョンは、以下の通りです。
- Keras v1.2.2
- Tensorflow v1.0.0
- OpenCV v3.1.0-dev

KerasやTensorflowが古いバージョンとなっています。
環境構築するにあたりpip等で直接ライブラリのバージョンを変更することも可能ですが、今回はAnacondaの仮想環境管理機能をを用いて設定します。
(環境構築に慣れていない方は、こちらの記事にpip,condaの基本的なコマンドをまとめたので参照下さい)

インストール

ソースコードをインストールします。

$ git clone https://github.com/rykov8/ssd_keras.git
$ cd ssd_keras

学習済み重みデータのダウンロード

重み付きデータはこちらに公開されていますので、プロジェクト直下にダウンロードしておきます。

Anaconda仮想環境設定ファイルのダウンロード

Anaconda仮想環境設定ファイル(ykov8_ssd_keras.yaml)を作成しましたので、こちらをプロジェクト直下にダウンロードします。

仮想環境への切り替え

ダウンロードした設定ファイルを用いて仮想環境へ切り替えます。

conda env create -f ykov8_ssd_keras.yaml
source activate rykov8_ssd_keras

ソースコードの一部修正

一部エラーコードの修正、及び検出結果の表示/書き出しの為、以下の通りソースコードを修正します。

/testing_utils/videotest.py
# 87行目(修正)
vidw = vid.get(cv2.CAP_PROP_FRAME_WIDTH)
vidh = vid.get(cv2.CAP_PROP_FRAME_HEIGHT)

# 99行目(追加)
num_frame = 0

# 163行目(追加)
print(text)

# 183行目(追加)
print(text)
cv2.imwrite("frame_" + str('{0:04d}'.format(num_frame)) +".png", to_draw)

# 184行目(追加)
num_frame += 1

動画ファイルの指定

動画ファイルを用意して、パスを指定します。

/testing_utils/videotest_example.py
# 24行目を修正して、自身の動画ファイルを指定
vid_test.run('./myvideo.mp4')

予測実行

videotest_example.pyを実行します。

cd testing_utils/
python videotest_example.py 

コンソールの最後にDone!と表示されたら終了です。

(省略)
person 0.61
person 0.83
person 0.72
dog 0.78
person 0.61
person 0.75
dog 0.75
dog 0.73
Done!

検出結果をgif動画に変換

videotest.pyに追加した183行目cv2.imwrite()にて出力した画像は、ImageMagickのconvertコマンドでgifに変換しました。

convert -adjoin out/*.gif output.gif

実行結果

  1. 暗い場所でも激しく動いても問題ないようです。
    3.gif

  2. 人混みもかなり良く認識できています。
    crowd.gif

  3. 水に入っているシーンでは精度が下がるようです(恐らく学習データに含まれていなかったのだと予想)
    4.gif

  4. 被写体が小さすぎると認識できないようです。(こちらも学習データにおけるラベル付けの前提の問題かと)
    5.gif

感想

最初の環境構築に時間が取られてしまいましたが、Anacondaでの仮想環境切り替えが知見として溜まったので良かったです。
また、前回試したYOLOの結果とは学習データも予測データも異なっていて比較できていないので、今度は条件を揃えた上で学習させて精度を比較していきたいと思います。
その際、学習に関してはローカルPCだと厳しいのでAWSのディープラーニング用AMIを利用したいと思います。

参考