やること
- 前回記事では SSD で物体検出してみましたが、今回は YOLO v3 で物体検出をしてみました
手順概要
-
- コードのダウンロード
-
- 学習済モデルのダウンロード
-
- モデルの変換
-
- コードの修正
-
- コードの実行
-
- tiny モデルの使用
実行環境
- macOS Catalina 10.15 beta
- python 3.7.4
- tensorflow 1.14.0
- keras 2.2.4
- pillow 6.1.0
1. コードのダウンロード
- 以下から keras 版の yolov3 をダウンロードします
$ git clone https://github.com/qqwweee/keras-yolo3
2. 学習済モデルのダウンロード
- 学習済モデルを下記コマンドで取得します
$ wget https://pjreddie.com/media/files/yolov3.weights
3. モデルの変換
- 入手した学習済みデータを Keras 用に変換します。以下のコマンドを入力します
- これで Keras 用の学習済みデータが「model_data」フォルダに入ります(yolo.h5)
$ python convert.py yolov3.cfg yolov3.weights model_data/yolo.h5
4. コードの修正
- yolo_video.py を実行すると下記エラーが出力されるため(ファイル自体は出力可能?)、コードを修正します
AttributeError
Traceback (most recent call last):
File "yolo_video.py", line 75, in <module>
detect_video(YOLO(**vars(FLAGS)), FLAGS.input, FLAGS.output)
File "/Users/XXXXX/anaconda_project/keras-yolo3/yolo.py", line 191, in detect_video
image = Image.fromarray(frame)
File "/Users/XXXXX/anaconda3/envs/yolo_v3_keras/lib/python3.7/site-packages/PIL/Image.py", line 2642, in fromarray
arr = obj.__array_interface__
AttributeError: 'NoneType' object has no attribute '__array_interface__'
- 下記の通り、191行目に例外処理(frame が NoneType になった場合)を追加します
yolo.py
# before
while True:
return_value, frame = vid.read()
image = Image.fromarray(frame)
# after
while True:
return_value, frame = vid.read()
if type(frame) == type(None): break
image = Image.fromarray(frame)
5. コードの実行
- 下記コマンドにて動画ファイルを指定し、物体検出を実施した結果を出力します
コードの実行
$ python yolo_video.py --input AAA.mp4 --output AAA_out.mp4
6. tiny モデルの使用
- 前回記事で SSD を実行した時もそうでしたが、私の環境は CPU のみで実行しているため、実行速度が遅いです
- そこで重いフルモデルではなく、軽い tiny モデルを使います
- tiny モデルは yolo-v3 の計算が少ないモデルなので、CPU でも使いやすいとのことです
- tiny モデルは精度は落ちますが、速いことが特徴です
- #2、#3同様にモデルのダウンロード及び変換を行います
$ wget https://pjreddie.com/media/files/yolov3-tiny.weights
$ python convert.py yolov3-tiny.cfg yolov3-tiny.weights model_data/yolo-tiny.h5
- また、yolo.py をコピーして、新たにyolo_tiny.py を作成します。
- そして23~24行目のパスを以下の通りに変更します。
yolo_tiny.py
# before
"model_path": 'model_data/yolo.h5',
"anchors_path": 'model_data/yolo_anchors.txt',
# after
"model_path": 'model_data/yolo-tiny.h5',
"anchors_path": 'model_data/tiny_yolo_anchors.txt',
- 加えて、yolo_video.py をコピーして、yolo_video_tiny.py を新たに作成します
- そして3行目の import を以下の通り yolo.py から yolo_tiny.py へ変更します。
yolo_video_tiny.py
# before
from yolo import YOLO, detect_video
# after
from yolo_tiny import YOLO, detect_video
- これで実行する準備が出来たので、#5のようにコードを実行します
コードの実行
$ python yolo_video_tiny.py --input AAA.mp4 --output AAA_tiny_out.mp4
実行結果
- 私の環境では CPU のみ使用しているため、前回実行した ssd も今回実行した yolo の何れも処理が遅かったです
- tiny モデルを使用した処理は上記に比べて早くなりましたが、精度(bounding box)も悪くなった印象です
ソースコード