YOLOXの映像解析で車両の速度をAIで算出して渋滞を判定するのに苦労した～その１：リアルタイム処理編

![vlcsnap-2022-10-25-20h48m50s729.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140663/90100dde-1a74-fb28-8459-4cc1d69eacc6.png)

2023/1/23追記：ストリーミング対応の新規記事を追加しました。24時間など長時間ストリーミングを安定受信して映像解析する苦労話を記載しています。最後の「関連記事」からご参照ください。

# サマリー
・システム開発の目標
・YOLOXの処理速度をあげるには？
・モデルごとの検出精度

これからYoloXを使って映像から通行する車両の速度を算出し、渋滞状況を判定するのに苦労した話を何話かに分けて書きます。
技術的なスコープとしては、YOLOXの処理速度と検出精度の向上、速度の算出方法とノイズの除去、渋滞の表現などです。今回はリアルタイム処理のためにYOLOXの処理速度と検出精度の向上をどのように行ったか説明します。

なおこの渋滞検知システムは[Traffic Jam Blade](https://youtu.be/OHDSoWFlcAI)としてすでに完成しており、リンクから20分のサンプル動画をご覧いただけます。渋滞発生は動画の最後の方になります。


# システム開発の目標

「渋滞」とは、[NEXCO西日本の定義]([https://www.w-nexco.co.jp/forecast/trafficjam_comment/index.html)によると「時速40km以下で低速走行、あるいは停止発進を繰り返す車列が1km以上かつ15分以上継続した状態を指します。」とあります。これは一般道ではなく高速道路の定義ですが、分かりやすいですね。ただ1台のカメラで1kmの車列をすべて写すのは無理なので、平均速度と車の台数から割り出すことにします。

実はAIを使った速度算出の実装は[以前](https://qiita.com/ComputerVision/items/d865f084c98a59349910)にもトライしており、その時は車間距離を算出するために映像上に2本のラインを引き、これらを通過する時間から速度と車間距離を算出していました。しかしこの手法は渋滞する道路では使えません。なぜならミッチリと車が詰まって動かなくなると、ラインを通過しないため速度も算出できなくなるからです。

![ライン2本による限界.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140663/1056e682-bcd9-350d-e315-9e205f7a1c3c.jpeg)

よって今回は映像に映っている車両を全てトラッキングしてリアルタイムで速度算出することにしました。
これにより映像内の車両の台数、そして平均速度が算出できるようになります。またリアルタイム処理を行うことで、「現在、道路が混雑しているのか空いているのか？（＝渋滞判定）」の判断もできます。

![vlcsnap-2022-10-29-18h44m34s038.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140663/80ce2804-8657-c005-cff4-08f3dd612f34.png)
![vlcsnap-2022-10-29-18h48m32s250.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140663/c9416bf0-e6c8-d317-fc01-c8699eab3107.png)
※この2枚の映像は下側の3車線のみを検出対象としており、上の画像で渋滞（本当は信号待ち）していたものが解消し始めてされて動き出したのが下の画像です。同じ車がやや前進し、速度表示も変化していることにご注目下さい。なお速度を表示しているラベルは、5km/h未満がオレンジ・5km/h以上が黄色で表示されています。

映像に映っている車両を全てトラッキングして速度算出し、渋滞状況を判定するには、リアルタイム処理が重要になります。
例えば24時間分の映像を24時間以内に処理できないと、リアルタイム処理とは言えません。
昨今はGPUの高速化や、YOLOシリーズでも処理速度と物体検出能力が向上したライブラリも登場していますが、まだまだ物体検知は処理に時間がかかる印象です。加えて今回はトラッキングや不要な車線を検出しないマスク処理などを加えておりこれにも処理時間がプラスされます。

これらの機能をすべて実装した状態でリアルタイム処理ができ、かつ満足できる検出結果が得らえるか？を検証してみました。

# YOLOXの処理速度をあげるには？

今回は商用利用を視野に入れているため、ライセンスの関係でYOLOXを採用しました。トラッキングにはこれまた高速なmotpyを利用しました。

YOLOXの処理速度向上に必要な要素は大まかにはGPU性能、入力する映像サイズ、使用するモデル(yolox_tiny.pthとかyolox_x.pthなど）となります。

使用したGPUはNVIDIAのRTX3090(24GB)です。ビットコインバブルがはじけて、GPUが普通の値段で買えるようになって本当に良かったですね（2021年の11月に30万円超えていたRTX3090のGPUボードが2022年の10月には18万円切るまで値下がりしました）。OSはWindows10 Proでメモリを64GB搭載したPCで計測しました。

今回、映像サイズと各モデルの処理速度についてベンチマークを取ってみました。
YOLOX+motpyでトラッキングし、後述する距離マスクや除外マスクなど、追加した機能をすべて入れたものです（映像出力はOFFにしています）。出力結果は以下の通りです。

60秒の映像を720pと1080pの2種類用意し、それぞれ5種類のモデルでの処理時間を計測しました。

| 30fps | yolox_tiny | yolox_s | yolox_m | yolox_l | yolox_x |
|:-:|:-:|:-:|:-:|:-:|:-:|
|  720p |  01:01.6 | 01:08.0  |  01:16.1 |  01:23.4 |  01:31.0 |
| 1080p  |  01:01.6 | 01:08.7  | 01:22.7  |  01:31.2 | 01:40.1  |

この結果から見ると、軽いモデルであるyolox_tinyとyolox_sは映像サイズの違いによる影響は受けにくいようですが、yolox_m以上の精度を上げたモデルでは映像サイズの違いが処理速度に出てます（映像が大きくなると処理時間がかかる）。

ただいずれにせよyolox_tinyで1分の映像を処理するのに1分以上かかっているので、このままではリアルタイム処理は無理です。
よって、処理を間引いて15fpsで処理した値は次の通りとなります。
※yolox_mの結果に実際の動画をリンクしております。

| 15fps | yolox_tiny | yolox_s | yolox_m | yolox_l | yolox_x |
|:-:|:-:|:-:|:-:|:-:|:-:|
|  720p |  00:33.3 | 0:00:37.1  |  [00:40.5](https://youtu.be/49WmLMrjGto) |  00:44.5 |  00:48.7 |
| 1080p  |  00:33.3 | 00:39.4  | [00:46.7](https://youtu.be/AJSRlLcaNCQ) |  00:50.9 | 00:55.2  |


結果としては60秒の映像を1コマ飛ばし(15fps)で処理すると、1080pの大きな映像で一番重たい（しかし精度が高いと言われている）yolox_xを使っても1分以内で処理できるため、リアルタイム処理は問題なさそうです。

# モデルごとの処理結果

処理速度の結果から、「遅いけど精度が高い」と言われているyolox_xまで問題なく使えることが分かりました。じゃあyolox_xでいいのか？というとそういう訳でもありませんでした。各モデルの処理結果を見てみましょう。
なお動画は[こちら](https://youtu.be/49WmLMrjGto)で42秒目あたりに検証対象とした2台の車両が登場します。比較したのは1334フレーム目で、2台が重なっている（物体検出的にちょっと難しい）状態です。2台の車両ですが、青い車両の方がやや早いです（速度差は10km/h以内程度）。

確認のポイントとしては上のタクシーの物体検出の枠が正確か（車両にフィットしているか？）、表示されている速度が正しいか（タクシーの方が10Km/h程度遅いか）です。

| 720Pの物体検出結果 |
|:-:|
| ![720p比較@1334_tiny.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140663/0bef8001-96d9-3745-1f3a-eded40521cdc.jpeg) |
| ![720p比較@1334_s.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140663/5fadc6c2-1ad7-1b78-3c81-405677f62a95.jpeg) |
|  ![720p比較@1334_m.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140663/05f692a1-0400-4bba-6721-3917def1f7a2.jpeg) |
|  ![720p比較@1334_l.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140663/f21aa6cf-556a-c773-2fa4-5c8ecbae874f.jpeg)|
| ![720p比較@1334_x.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140663/07533c1d-2f9c-8163-241c-40a1928e80e2.jpeg)|

今回は上のタクシーがユニークなカラーリングで、物体検知がやや難しかったようです。
yolox_tiny.pthでは3台の車両と認識しており精度が低すぎます。yolox_s.pthは物体検知の枠（バウンディングボックス）がずれており、結果として66k/mという異常な速度になっています。これも使えません。
yolox_m.pthとyolox_l.pthはどちらも問題ありません。速度も許容値です。
しかしyolox_x.pthは一番精度がいいはずなのに、物体検出の枠がズレて速度も2km/hとイマイチです。

| 1080Pの物体検出結果 |
|:-:|
| ![1080p比較@1334_tiny.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140663/ad59140c-5a8d-27be-ae44-bfc6f96af75a.jpeg) |
| ![1080p比較@1334_s.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140663/e38bdd2d-e882-5ae4-1808-a13ce4508113.jpeg)  |
|![1080p比較@1334_m.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140663/33bdcc8b-b8a1-af16-b19b-d35c91d0595c.jpeg)|
|![1080p比較@1334_l.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140663/c0909fc0-6e8d-c0f4-7d89-0371f5afac26.jpeg)|
|![1080p比較@1334_x.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140663/e846a83a-d07f-5d56-7fb1-e119d3aacd8e.jpeg)|

こちらは映像サイズが大きくなっていますが、検出結果はさほど変わりません。

yolox_tiny.pthでは2台の車両と認識しており、またyolox_s.pthは720Ｐとは違うものの「3台の車両」と誤検出しています。バウンディングボックスもかなりずれてます。これらは使えません。
yolox_m.pthとyolox_l.pthはどちらも問題ありません。速度も許容値です。
yolox_x.pthについては720Pと同様、一番精度がいいはずなのにバウンディングボックスがズレて速度も40km/hとイマイチです。

よって、これらの結果から映像は720P、モデルはyolox_m.pthを使うことにしました。

次の記事では速度算出の詳細とノイズ除去について解説します。

※720pの画像と比較すると、1080pの画像では速度設定をミスしており（720pの速度設定をそのまま1080pで使用してしまった）、速度が同じではありません。画像を全部用意してから気づいたミスなので、時間があるときに修正します・・・。

# 関連記事
・[2023年：裏技公開！ AI映像解析で物体検出精度をあげる簡単テクニック](https://qiita.com/ComputerVision/items/1bb9861d0b55b0161818)
・[2023年：24時間以上ストリーミングさせるとトラブルばかりで苦労した](https://qiita.com/ComputerVision/items/26a72a3f83fcf6c5d0d1)
・[2022年：AI映像解析で車両の速度を自動算出すると異常値ばっかりで苦労した](https://qiita.com/ComputerVision/items/fcd39dcb272edf37518c)
・[2022年：YOLOXの映像解析で車両の速度をAIで算出して渋滞を判定するのに苦労した～その１：リアルタイム処理編](https://qiita.com/ComputerVision/items/5283a0ebbb59d5a4cb8f)
・[2022年：YOLOXの映像解析で車両の速度をAIで算出して渋滞を判定するのに苦労した～その２：速度算出手法編](https://qiita.com/ComputerVision/items/a86f20673df6b6536345)