工場長のブログ

日々思ったことを書いてます。

S+ Camera Basic + Deep SORTでリアルタイムトラッキング(前編)

今日はSORACOM Advent Calendar 2020のネタとして、S+ Camera BasicでDeep SORTを動かすことに挑戦してみたいと思います。

 

先にお断りしておきますと、残念ながら今日の時点ではS+ Camera Basic実機で動かすところまでたどり着いておらず、以下のようなシリーズ物として綴っていく予定ですorz

1. Deep SORTについてのおさらいと、まずはMacでas isで動かしてみる (←このポスト)

2. S+ Camera BasicでDeep SORTを動かす

 

Deep SORTってなに?

Deep SORTは映像のなかに映っている、複数のオブジェクト(例えば人)を同時に、かつ連続的にトラックしていくための手法のひとつで、Simple Online and Realtime Tracking with a Deep Association Metricというタイトルで論文(Wojke, Bewley, Raulus. (2017). Simple Online and Realtime Tracking with a Deep Association Metric)が投稿されており、この手法を利用することで、例えば通行量調査を実装することができます。画面の左から移動してきた人が、画面中央のボーダーラインを越えたらカウントする。また右から左に向かって移動する人に対しても同様の処理を行う、といったイメージで。

f:id:imai-factory:20201219134357p:plain

(画像参照元https://motchallenge.net/vis/MOT16-04/det/ )

 

移動体のトラッキングは単純なObject Detectionと違い、前のフレームに映っていた「あのひと」と現フレームに映っている「このひと」が同じ人かどうかを評価、同定してやる必要があります。場合によってはトラッキング対象が一時的に物陰に入ってしまったりといったような課題も出てきます。この種の問題はMulti Object Trackingと呼ばれ、MOT Challengeというコンペティションも開かれていて、上記の画像はこのMOT Challengeのデータセットのひとつです。

Deep SORTも、MOT16のデータセットに対して以下のような成績をマークしていると前述の論文中で語られています。一番したの行がDeep SORTによるデータです。

f:id:imai-factory:20201217170742p:plain

(当図表は論文より)

 

S+ Camera Basicとは?

S+ Camera Basic(サープラスカメラ、と読みます。以下、S+ Cameraと略します。)はソラコムが開発、販売するプログラマブルなネットワークカメラデバイスです(コネクティビティはもちろんSORACOM Airです!)。S+ CameraはSORACOM Mosaicという「エッジデバイス統合管理サービス」によって管理され、通信回線を通じてアプリケーションデプロイやシステムメンテナンスが行えるため、一度現場に配備したあとでも簡単にアプリケーションの更新が可能です。

このカメラの特徴としては、電源を挿すだけでオンラインになり、書き込まれたプログラムが動作し始める、プログラムはPythonで開発できる、デプロイはSORACOM Mosaic経由でオンラインで行えることが上げられます。つまり、アプリケーション開発者はPythonでの画像処理の部分、言い換えればビジネスロジックの開発にリソースを集中することができます。

なぜS+ Camera BasicでDeep SORTを?

わたしは2020年現在、株式会社ソラコムでソリューションアーキテクトとして仕事をしており、S+ Camera Basicを使ったIoTアプリケーションの設計や開発をされるお客様のお手伝いをしています。カメラを使ったIoTのユースケースとして多いのが、OCRによる文字読み取りやメータの読み取り、そして混雑度の数値化が挙げられます。混雑度の数値化については、単純なやり方としてはObject Detectionを使って、画面内に映っている人の人数を数えるというやり方があり、これはこれで有効なケースがあります。一方、人の流れを把握したい、例えば人がどこから入ってきてどこに抜けていった、というようないわゆる人流みたいなところまで取りたくなってくると、カメラでやろうとすると今回の議論にあるようなDeep SORTのような手法が必要になってきます(カメラ以外でやるなら、人の通るところにセンサーを設置していくという方法もあります。これはこれで、多くの人を同時に(かつ別々に)センシングするのが難しい、などの考慮事項もあります)。これまで仕事でDeep SORTの話をすることはちょいちょいあったのですが、自分でしっかり使い込んだことがなかったというのがなんとなく引っかかっていたので、今回、がっつり触っておこうと思ったというのが今回のモチベーションです。あとはサンプルコードとして公開しておけば後々の自分の仕事も楽になるかなというのもあり笑

Deep SORTの処理概要

さて、中身について少し見ていきましょう。前述のような問題をDeep SORTはざっくり以下のようなアプローチで解決していきます。

  1. 画面内に映っているものをObject Detectionする
  2. 検出されたオブジェクト群と前のフレームのオブジェクト群を「前フレームまでの移動量をもとに計算した現フレームでの予測位置範囲」と「見た目の類似性」という、主に2つの情報をもとに比較、同定していく

位置の予測についてはカルマンフィルタ、見た目の類似性についてはベクトル化した対象画像のコサイン類似度を使って計算をします。

1フレームごとにDeep LearningベースのObject Detectionを行い、発見された各オブジェクトに対してCNN等を活用したベクトル化、そして前フレームのオブジェクト群とのカルマンフィルタとコサイン類似度の比較を行うということになりますので「重い処理」と言っても差し支えないと思います。それでもMOT16のなかでは速いほうの部類にあるようですが(前出の図表中のRuntimeの比較にも現れていますね)、Raspberry PiのCPUだけで現実的なリアルタイムトラッキングを行うには厳しいでしょう。

ひとまず動かしてみよう

ではまずは動かしてみましょう。論文の著者であるNicolai Wojkeによる参考実装もありますがここでは下記の実装を利用してみたいと思います。詳細は後述していきますが、Object Detection部分をCoral Edge TPUのサポートを受けるTFLiteへの切り替えがしやすそうな実装だったことが理由です。

github.com

 

Tensorflow + CPU(Mac Book Pro。M1ではない) で動かしてみました。いちばん処理量の多いであろうObject DetectionのアルゴリズムはYOLOv4です。1.2〜1.3FPSという感じですね。やはりなかなか重い。Mac Book Proでこのレベルですから、S+ Camera BasicのコントローラであるRaspberry Pi4では相当厳しいでしょう。

 

次にObject Detectionの部分を前述のようにCoral Edge TPUサポート付きのTFLiteによるMobileNet SSDv2に切り替えてみました。10FPS前後出るようになっていますね!Coral Edge TPUはRaspberry Pi4でも動作がサポートされていますし、S+ Camera Basicでも動作確認が取られていますので、これは期待できそうですね。

今日はここまで。次回はS+ Camera Basicで動くようにしてみましょう

今日はこのへんで。年内にS+ Camera Basicで動かすところまで行けたらなと思っています!上記、Coral Edge TPUでDeep SORTを動かしているコードも、次回あたりに向けて公開はしていきたいと思っています。(いまはかなりmessな状態なのでちょっと無理ですw

9/30 200m坂ダッシュ x 12

前回の坂ダッシュがつらすぎたので今日はゆっくり目からスタート。ラスト1本はたぶん自己ベスト。

コンディション

  • 23℃
  • 50%
  • 8.1km/hour

タイム

  RUN REST
1 45 79
2 44 79
3 43 81
4 44 81
5 43 87
6 44 80
7 43 80
8 43 82
9 43 86
10 42 85
11 44 88
12 40  
平均 42.9 83.33333333

 

心拍

  • 平均: 144
  • 最大: 197

9/26 15kmペース走 4'00/km

いままでで一番長いペース走。ミズノのサブスリーメニューで一番きつそうなやつ。5kmを越えたあたりから余裕が出てきた。最後の1kmのそれなりにスパート効いた。

先週に引き続き、やっぱり(終わったあと)お腹壊した。負荷に対して腹筋が足りないのかな・・?

コンディション

  • 22℃
  • 82%
  • 北北東の風 10.4km/hour

タイム

  タイム 備考
1 3:56  
2 3:28 1025m
3 3:58 1025m
4 3:58 1025m
5 3:53  
6 4:01 1025m
7 4:04 1025m
8 3:59 1025m
9 3:55  
10 4:01 1025m
11 4:03 1025m
12 4:08 1025m
13 4:07 1025m
14 4:01  
15 3:51 1025m

 

心拍

  • 平均: 174
  • 最大: 192

9/19 1000mインターバル x 12 3'40/km

11本目でお腹壊して撃沈。12本目はヘロヘロでなんとかゴール。終わったらお腹痛くてトイレに駆け込み。その後も歩いて帰れずタクシーで帰宅w

コンディション

  • 23℃
  • 91%
  • 東北東の風 15.0km/hour

タイム

  RUN REST 備考
1 3:38 56  
2 3:45 65 1025m
3 3:55 72 1025m
4 3:49 74 1025m
5 3:51 81 1025m
6 3:47 87 1025m
7 3:49 82 1025m
8 3:49 80 1025m
9 3:50 120 1025m
10 3:47 84  
11 4:00 103 1025m
12 4:23   1025m


心拍

  • 平均: 171
  • 最大: 199

 

9/16 200m坂ダッシュ x 12

一本目の入りがまあまあ速かったのでそのまま頑張ったら平均タイムでベスト更新。

コンディション

  • 25℃
  • 79%
  • 風 7.5km/hour

タイム

  RUN REST
1 42 89
2 42 83
3 42 84
4 41 87
5 41 85
6 41 90
7 41 85
8 41 91
9 42 90
10 40 86
11 41 94
12 42  
平均 41.2 88

 

心拍

  • 149-198

 

9/12 12kmペース走 4'00/km

コンディション

  • 24℃
  • 87%
  • 東北東の風 10.8km/hour

タイム

  タイム 備考
1 4:03  
2 4:08 1025m
3 4:08 1025m
4 3:58 1025m
5 3:54  
6 4:03 1025m
7 4:02 1025m
8 4:00 1025m
9 3:57  
10 4:07 1025m
11 4:06 1025m
12 3:58 1025m

 

心拍

  • 161-194

 

9/9 200m坂ダッシュ x 12

コンディション

  • 33℃
  • 54%
  • 10.7km/hour

タイム

  RUN REST
1 44 78
2 43 79
3 43 86
4 42 85
5 42 86
6 43 89
7 42 91
8 43 90
9 41 95
10 42 94
11 41 95
12 41  
平均 42 90.11111111

心拍

  • 149-173