【YolactEdge】高速に画像から物体を検知してみた

画像解析

はじめに

今回はインスタンスセグメンテーションというAI技術をつかってみます。インスタンスセグメンテーションモデルとしては、以前紹介した物体検出アルゴリズムのYOLOから派生した、動画に特化した初のリアルタイムインスタンスセグメンテーションモデルであるYolactEdgeを使っていきます。インスタンスセグメンテーションを用いることで図-1のように1つの画像に複数の🐘が写っていた場合、それぞれを別々の物体と検出できます。
 

図-1 インスタンスセグメンテーションモデルによる検知例

インスタンスセグメンテーションとは

インスタンスセグメンテーションによって、重なっている物体を別々に検出できます。画像の中にある物体の領域を特定し、個体ごとに領域分割して物体の種類を認識できる手法です。各物体に対して、異なるIDを与えるため、図-2のように1つの画像に検知対象が複数写っている場合、それぞれを別々の物体と検出します。
さらに、空や道路などの物体ではないものはラベルを与えません。

図-2 Yolact Edgeによる検知例

YolactEdgeについて

YolactEdgeは、Real-time Instance Segmentation on the Edgeと呼ばれ、処理が高速でリアルタイムに動作可能な Instance Segmentation モデルです。MS COCOデータセットを用いた実験では、既存のリアルタイム手法に比べて3~5倍の速度向上を実現し、検出精度は見劣りしないことが検証されています。
YolactEdgeでは、Yolactから下記2点の改良をおこなっています。
①速度と精度を慎重にトレードオフしながらTensorRT最適化を適用。
②動画の時間的冗長性(時間的に近いフレームは相関が高い)を利用した新しい特徴ワープモジュール

キーフレーム(図-3の左)から非キーフレーム(図-3の右)に特徴のサブセットを変換することにより、バックボーン計算を削減しています。具体的には、非キーフレームにおいて、高解像度であるためマスク予測に重要なC3特徴量を容易に計算することができます。これにより、非キーフレームでの精度を維持したまま、大幅に高速化することができています。

図-3 Yolactからの拡張

FlowNetSは、下記の2段階でフロー推定をおこないますが、Yolact Edgeでは、①の代わりに、ResNetバックボーン(C3)から特徴を再利用し、より少ない畳み込み層を使用しています。
①RGB画像を入力として受け取り、特徴のスタックを計算しています。
②大きな動きと小さな動きの両方を運ぶ粗から細への特徴を生成するために、特徴マップを再帰的にサンプリングし連結して特徴のサブセットを精製する。

図-4 FlowNetSとYolact EdgeのFeatFlowNetの違い

詳細は下記論文まで。
Liu, Haotian, et al. “Yolactedge: Real-time instance segmentation on the edge.” 2021 IEEE International Conference on Robotics and Automation (ICRA). IEEE, 2021.

YolactEdgeの実装

環境

Google Colabで簡単に動かせるようになっているため、それに添って説明していきます。自分で動かしてみたい方は、下記URLをクリックし表示されたページの先頭にあるOpen in Colabをクリックすると動かせます。

https://github.com/cedro3/yolact_edge/blob/master/YolactEdge_demo.ipynb

実行準備

ノートブックを開いたら、ファイルのタブから「ドライブにコピーを保存」をクリック。YolactEdge_demoのコピーを作れたら、ランタイムのタブから「ランタイムのタイプを変更」をクリック。そして、ハードウェアアクセラレータからGPUを選択します。その後、セットアップのコードを実行していきます。

セットアップ

静止画を物体検出

物体検出させたい画像をyolact_edgeフォルダの中のpicフォルダ下にアップロードします。今回検知させたい画像を下記のコードで表示します。なお、検知させたい画像は下記からダウンロードしました。←素材が豊富でおすすめです。
https://pixabay.com/ja/

実行

さっそくインスタンスセグメンテーションをやってみましょう。下記のコードを実行してください。

引数
–trained_model:学習済モデルのパスを指定
–score_threshold:物体を検出する閾値
–top_k:検出数
–image:入力する画像データのパスを指定。
–output_img:出力する画像データのパスを指定
–disable_tensorrtTensorRTを使わない

結果


人、サーフボードを検知しています。一方、空や地面などの物体ではないものはラベルを与えていません。

ビデオから物体検知

物体検出させたい画像をyolact_edgeフォルダの中のvideoフォルダ下にアップロードします。今回検知させたい動画を下記のコードで表示します。なお、検知させたい動画はサーフィンが趣味である私が最近GoProで撮影したものです。

実行

さっそくインスタンスセグメンテーションをやってみましょう。下記のコードを実行してください。

引数
–trained_model:学習済モデルのパスを指定
–score_threshold:物体を検出する閾値
–top_k:検出数
–video:入力する動画データのパスを指定。
–output_video:出力する動画データのパス指定
–disable_tensorrtTensorRTを使わない

※今回、下記のコードを実行してもエラーが出て検知結果をGoogle Colab上で確認できなかったので、output_videoをダウンロードして手動で確認しました。
現在エラーについて調査中です

結果

上記の動画が、runs/track/expフォルダの中に生成されました。バウンディングボックスには、ラベルと信頼度が記載されています。

まとめ・考察

今回は、サーファーのインスタンスセグメンテーションをしてみました。検知する前と検知した後を比較してみると、かなり上手く検知してくれることがわかります。

一方で、下記2点が問題だと感じました。
・遠くの人物は検知されにくい
・水しぶきを鳥(bird)と検知してしまっているフレームがあった

2つ目の課題は、閾値(threshold)を上げる対策で解決できるのではないかと考えています。
人とサーフボードが近くで一緒に検知された時にそれをサーファーだと定義するスクリプトを書けば、アノテーション(大変な作業)をしなくてもサーファーを検知することも可能になると思いました。

タイトルとURLをコピーしました