SE_BOKUのまとめノート的ブログ

SE_BOKUが知ってること・勉強したこと・考えたことetc

静止画像と動画からの物体検出(Yolo3)をやってみる。/tensorflow v1+keras-yolo3

f:id:arakan_no_boku:20190312234802j:plain

目次

物体検出(Yolo3)をやってみる

DeepLearningベースの物体検出(Yolo3)のQuick Startをやってみました。 

なお、本記事で紹介する「kelas-yolo3」はtensorflow2.0では動きません。

tensorflow2.0で試す場合はこちらを参照してください。

arakan-pgm-ai.hatenablog.com

物体検出は画像の中に含まれる物体の位置とカテゴリー(クラス)を検出する手法です。 

アウトプットはこんな感じになります。

f:id:arakan_no_boku:20191223220730p:plain

これが、有難いことに「keras-yolo3」を使えば簡単に試すことができます。

実行にはtensorflowが必要です。

kerasはtensorflowをインストールすると、一緒にはいります

keras-yolo3をダウンロード

GitHubのこちらのサイトからZIPでダウンロードします。

github.com

こんな画面です。

f:id:arakan_no_boku:20190313230859j:plain

ZIPファイルをダウンロードしたら、どこか適当な作業フォルダに解凍します。

この解凍したフォルダが作業フォルダになります。 

Quick Start

上記サイトに、以下の手順が書いてあります。

Quick Start


Download YOLOv3 weights from YOLO website.
Convert the Darknet YOLO model to a Keras model.
Run YOLO detection.


wget https://pjreddie.com/media/files/yolov3.weights
python convert.py yolov3.cfg yolov3.weights model_data/yolo.h5
python yolo_video.py [OPTIONS...] --image, for image detection mode, OR
python yolo_video.py [video_path] [output_path (optional)]

これをやります。 

Quick Start:Download YOLOv3 weights from YOLO website 

学習済のWeightファイルをダウンロードします。

上記手順だと、wgetを使う方法になってますが、こちらのサイトからダウンロードするほうが簡単です。 

pjreddie.com

この真ん中あたりに、以下のように書いてあるところがあります。

f:id:arakan_no_boku:20190313235135j:plain

この黄色で囲った部分「here(237MB)」をクリックすると、「yolov3.weights」ファイルをダウンロードできます。

先に解凍した「keras-yolo3」フォルダに保存します。

f:id:arakan_no_boku:20190313235501j:plain

Quick Start:Convert the Darknet YOLO model to a Keras model.

上記でダウンロードした「yolov3.weights」は、そのままではkerasで使えないので、kerasモデルにコンバートします。

コマンドプロンプトを立ち上げて、「keras-yolo3」フォルダをカレントフォルダにして、tensorflowが動く仮想環境をActivateします。

そこで、以下のコマンドを実行します。

python convert.py yolov3.cfg yolov3.weights model_data/yolo.h5

インプット・アウトプット(model_data/yolo.h5)のファイル名等は絶対に変更しないで、このまま動かす必要があります。

どうも、次のプログラムは、カレントフォルダに「model_data/yolo.h5」がある前提で動くみたいですから。 

Quick Start:物体検出する画像か動画を用意する

適当に画像・動画を用意します。

この「keras-yolo3」の学習済ウェイトを使うと以下の物体検出が可能です。

英語名 日本語名
person
bicycle 自転車
car
motorbike バイク
aeroplane 飛行機
bus バス
train 列車
truck トラック
boat ボート
traffic light 信号機
fire hydrant 消火栓
stop sign 一時停止標識
parking meter パーキングメーター
bench ベンチ
bird
cat ネコ
dog
horse うま
sheep
cow
elephant
bear くま
zebra シマウマ
giraffe キリン
backpack バックパック
umbrella
handbag ハンドバッグ
tie ネクタイ
suitcase スーツケース
frisbee フリスビー
skis スキー
snowboard スノーボード
sports ball スポーツボール
kite
baseball bat 野球用バット
baseball glove 野球グローブ
skateboard スケートボード
surfboard サーフボード
tennis racket テニスラケット
bottle ボトル
wine glass ワイングラス
cup カップ
fork フォーク
knife ナイフ
spoon スプーン
bowl ボウル
banana バナナ
apple 林檎
sandwich サンドイッチ
orange オレンジ
broccoli ロッコ
carrot にんじん
hot dog ホットドッグ
pizza ピザ
donut ドーナツ
cake ケーキ
chair 椅子
sofa ソファー
pottedplant 鉢植え
bed ベッド
diningtable ダイニングテーブル
toilet トイレ
tvmonitor テレビモニター
laptop ノートパソコン
mouse マウス
remote リモコン
keyboard キーボード
cell phone 携帯電話
microwave 電子レンジ
oven オーブン
toaster トースター
sink シンク
refrigerator 冷蔵庫
book
clock クロック
vase 花瓶
scissors はさみ
teddy bear テディベア
hair drier ヘアドライヤー
toothbrush 歯ブラシ

 この辺が映っている写真(画像)や動画を用意して、適当なフォルダに保存します。

自分は今回、こういう写真を使いました。

sample.jpgという名前にしています。

f:id:arakan_no_boku:20190314001042j:plain

 

静止画像(写真)でRun YOLO detection.(物体検出実行)

以下のコマンドを実行します。

python yolo_video.py --image 

そうすると、しばらくすると画像ファイルの入力を求めてきます。

f:id:arakan_no_boku:20190314222736j:plain

ここに画像をフルパスで入力すると、しばらくすると、BMPファイルに関連づけられているソフトで画像が表示されます。

こんな感じ。

f:id:arakan_no_boku:20190314224217j:plain

真ん中のナプキンが「cake」になっている以外は、まあまあ、正しく検出されてます。

動画でRun YOLO detection.(物体検出実行)

以下のコマンドを実行します。

python yolo_video.py --input [input video file] --output [output video file]

例えば、こんな感じです。

python yolo_video.py --input C:\inputs\sample.mp4 --output C:\outputs\result.mp4

動画の物体検出がエラーになる場合・・その1

すんなり動けばラッキーなのですが、エラーになる場合があります。

例えば。

ModuleNotFoundError: No module named 'cv2' 

これは、openCVがインストールされてないことが原因のエラーです。

解決するために、以下のように、pipでインストールします。

pip install opencv-python

ちなみに・・。

ネットで上記エラーメッセージで検索すると、CV2はpython2.xxの対応なので、Python3の場合だとちょっと面倒な手順が必要・・みたいな情報があったりしますが、実際は openCV は「CV3」も「CV2」も両方とも、importは「cv2」のはずです。

だから、大丈夫だろうと思って「python3.6」環境でpipだけでやったのですが、問題はなかったです。 

動画の物体検出がエラーになる場合・・その2

こんなエラーがでる場合もあります・・というか、かなりの確率ででます。

Traceback (most recent call last):
File "yolo_video.py", line 75, in <module>
detect_video(YOLO(**vars(FLAGS)), FLAGS.input, FLAGS.output)
File "C:\XXXXX\Yolo3\keras-yolo3\yolo.py", line 191, in detect_video
image = Image.fromarray(frame)
File "C:\XXXXXXX\AppData\Local\conda\conda\envs\tensorflow\lib\site-packages\PIL\Image.py", line 2483, in fromarray
arr = obj.__array_interface__
AttributeError: 'NoneType' object has no attribute '__array_interface__'

これは、ちょっとやっかいです。

この部分

「yolo.py", line 191, in detect_videoimage = Image.fromarray(frame)」

で「frame」がNoneTypeになっているのが原因で、何かを追加インストールするなどの方法では回避できません。

バグ?なんでしょうかね?

次のバージョンでの修正を期待しつつ、とりあえず、エラーを回避して、動画ファイルを出力させるの応急処置をほどこします。

yolo.pyの190行目と191行目の間に「if type(frame) == type(None): break」を入れます。

こんな感じ。

return_value, frame = vid.read()
if type(frame) == type(None): break
image = Image.fromarray(frame)

これで、とりあえずエラーはとまります。

ですが、Nontypeになった最後のフレームを捨ててしまうという荒療治なので、本当の応急処置ではあります。

本当は、 vid.read()関数でframeがNonTypeを返さないように修正するべきなんでしょうが、そこまでやると・・ねえ・・大変なので。 

動画の物体検出結果の動画ファイルを保存

結果を動画で保存すると、こんな感じでペコペコ認証していくのが見えてなかなか面白いですが・・CPUだけのPCだと、わずか数秒の動画でも、結構検出と動画アウトプットを生成するのに、けっこう時間がかかります。

自分のPCでは、たった4秒の動画を変換するのに、2分~3分くらい、コマ送りみたいな画像を眺めるはめになりました。

でかい動画でやるときは、それなりの覚悟でどうぞ。

f:id:arakan_no_boku:20190314231430j:plain

参考までに

念のため、

理論的なことに興味がでてきた時用に参考になりそうなサイトを貼っておきます。

qiita.com

上記の論文の最後の方に「YOLOv3を理解するには当然YOLOv2, YOLO,さらに遡ってRCNN, Fast RCNN, Faster RCNN, SSDも理解しておく方が良いです.」と書いてあるので、そのあたりを勉強するのにわかりやすそうなリンクもあわせて貼っておきます。

blog.negativemind.com

ではでは。