LoginSignup
15
22

More than 5 years have passed since last update.

YOLOv3+pythonで車載動画中のバイクを認識し動画にする

Last updated at Posted at 2018-05-23

リアルタイムに物体認識できるYOLOですが、最近YOLOv3が登場しました。
これを使って、試しに簡単な動画解析プログラムを組んでみます。

さて、私は、趣味でバイクに乗っていて、ドライブレコーダー代わりに、安価なアクションカメラを付けて、動画を撮影することがあります。
ただ、車載動画は撮影しても、長すぎて全部見返すことはほとんどありません。いいシーンだけ抜き出してくれればなぁと常々思っています。

ところで、バイク同士がすれ違うときに、軽く手を降るなど挨拶する文化があり、YAEH(ヤエー)と呼ばれています。
市街地ではほとんどないですが、ツーリングスポットでお互い集団だと時々ヤエーされたりします。
youtubeには多くのヤエー動画がアップロードされてます。

YOLOを使って、バイクとのすれ違いシーンをうまく切り出すことができれば、「YAEH(っぽいところ)動画」を自動的に作ることができそうです。見返すのも楽しくなりそうですね。

というわけでやっていき。

結局どういうのができるの

こういう動画から、
元の動画

画像中のバイクの数を認識して、こういう動画を作ります。
自動編集した動画

すれ違ってない部分も多いですが、バイクとのすれ違いシーンはおおかた抜き出せてるのでは、と思います。
ただ、(私が)全くヤエーしてなくて、もうちょっといいサンプルが必要ですね…

環境

動画から物体認識するので、高性能のGPUは必須です。
それ以外は、特に制約はありませんが参考まで。

OS:Ubuntu 16.04
GPU:GTX1080 (cuda9.1)
メモリ:16GB
動画フォーマット:MOV, 1280*720 60FPS

python3(anaconda3-5.1.0)を使いました。
また、OpenCV, CUDA, cudnnは予めインストールしています。
ちなみにOpenCV3.4.1だとdarknetのmakeできないIssueがあるようで、ハマりました。
OpenCVは3.4.1ではなく、3.4.0を使いましょう。

YOLOのインストール

YOLOは公式のdarknetでの実装を利用します。公式通りなので簡単に。

公式サイトの手順通り、darknetをcloneし、YOLOv3のconfig fileをダウンロードします。
ただし、CPUだと1画像(1フレーム)十数秒~かかるので、動画の場合はCompiling With CUDAを参考に、CUDAとOpenCVを有効にして、makeします。

makeが通り、detectが利用できれば問題ないと思います。

./darknet detect cfg/yolov3.cfg yolov3.weights data/dog.jpg

pythonからdarknetを利用する

darknetにはpython用のAPIとサンプルコードが用意されています。

  • python/darknet.py
  • examples/detector-scipy-opencv.py

今回、python3を利用するので、2to3を使い、darknet.pyをpython3で動くようにしておきます。

2to3 python/darknet.py -w

また、python/darknet.py で libdarknet.so をフルパスで指定しておかないとうまく動かないことがあります。darknet.pyの L47-48あたりを修正しておきましょう。

#lib = CDLL("/home/pjreddie/documents/darknet/libdarknet.so", RTLD_GLOBAL)
lib = CDLL("libdarknet.so", RTLD_GLOBAL)

動画解析のコードを書く

サンプルコードを参考に実装していきます。
実装コードはここのgistにあげました。

動画の読み込み/書き込みにはscikit-videoを使っています。

認識は0.18秒/1frame 程度で終わるので、デバッグ用のファイル出力をしなければ、1秒あたり2フレームを処理すると、10分の動画で、大体5分程度で終わります。全フレーム処理すると時間がかかるので間引いて処理しています。

実装では、YOLOで認識したバイク(motorbike)の認識結果をplotlyで可視化しています。
以下は、ある動画を解析した結果で、横軸がフレーム、縦軸がそれぞれのバイクの確率を表しています。

image.png

頻繁に1フレームだけバイクが検出されていて、ちょっとノイズが多いですね。より作りこむ場合には、この対策が必要です。
今回は、フレームごとに確率の総和を取り、適当なしきい値(1.8など)より大きい場合に、そのフレームを抜き出して、編集してみます。
すなわち1フレーム上に、複数台のバイクが存在していると、「バイクとすれ違った」と見なしています。

総和をとった結果はこちら。

image.png

ちょこちょこ、バイクを2台〜3台程度認識していることがわかります。
作成した結果は、上に上げたとおりです。

うまくいったり、いかなかったりした認識結果のフレームをいくつか参考に載せます。
バイクの認識結果だけを囲って表示しています。

18600フレーム目。いい感じですね。
image.png

33600フレーム目。なんか2台いることになってます。
image.png

32940フレーム目。遠くの自動車をバイクとして認識してしまっています。
image.png

28320フレーム目。自動車をバイクとしている以外は、いい感じ!
image.png

29160フレーム目。手前のバイクを認識してないですね… 奥の自動車をバイクとしています。
image.png

ざっと結果を見てみたところ、以下のような問題がありました。

  • 真後ろ・真正面のバイクを認識できない(見逃す)
  • 自動車をバイクと誤認識する(逆も多い)

しきい値を変えたりすることで緩和可能かと思います。

よりよい動画作成には、
* 誤認識(ノイズ)の扱い
* 自動車と認識した場合の対応、
* 認識したフレームの前後のフレームの利用
などが必要です。
もうちょっと作りこむ必要がありますね。

まとめとfeature work

YOLO使って、お手軽に動画解析し、動画を編集・作成するシステムを作りました。
しっかり取れることもありますが、1フレームのみでは、誤認識も多いのでうまく扱う必要がありそうです。

今回は、画像中のバイクの台数を利用して動画を作成しましたが、マスツーリングの場合には前に走っているバイクも含めてしまうので、対象物が迫ってきているのか(相対速度)を判別して「すれ違ったバイク」のみを認識する必要があるでしょう。
また、「ヤエー」そのものも認識したいです。が、体がバイクに隠れるので難易度高そうです。ポーズ推定(GoogleのPoseNetなど)を使ってみるのもありかもしれません。

動画解析サービス、例えば、Google Cloud Video Intelligenceとか、Azure Video Indexerとか、Amazon Rekognition Videoとかバシバシ登場してきてます。これらを用いればもっと簡単に・スケールするものが作れそうです。YOLOv3やTiny-YOLOv3との精度比較もしてみる価値はあると思います。

15
22
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
22