"BOKU"のITな日常

還暦越えの文系システムエンジニアの”BOKU”は新しいことが大好きです。

CPUのみWindows10マシンで物体検出のデモをやってみる。/yolo3・tensorflow・keras

CPUのみの非力なWindows10マシンでも、さくっと動かせる物体検出(Yolo3)のチュートリアルがあったので、やってみました。

f:id:arakan_no_boku:20190312234802j:plain

 

簡単でサクサク動くyolo3 

 

keras-yolo3を使います。

名前の通り、kerasが必要です。

なので、tensorflowをインストールしときます。

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

楽ですねえ。

まだの方はこちらを参照してインストールお願いします。

arakan-pgm-ai.hatenablog.com

 

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)]

これをやります。

 

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

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」がある前提で動くみたいですから。

 

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

 

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

この「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」になっている以外は、まあまあ、正しく検出されてます。

 

動画の場合

 

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

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

ではでは。