動画から顔検出認識をしてみる( insightface )

insightfaceという、WIDER FACE AND PERSON CHALLENGE 2019の顔認識で最終的な精度2位を取ったプロジェクトを試してみました
https://competitions.codalab.org/competitions/20146#results

顔検出・顔認識・同一人物のクラスタリング・可視化した動画生成までやってみました。
社員旅行の宴会場でぐるっと回って動画を撮影したもの使ってます

動画を連番画像に切り分け

ffmpegでサクっと

各画像毎に顔の位置検出を行う

顔検出はInsightface(の中にあるRetinaface)を使ってます。
DLIBでも顔検出が出来るのですが正面顔で大きくないと取得しづらいのに対して、RetinaFaceは横向きの顔や、マスク等で隠れた顔、極小サイズの顔まで検出可能です。

https://github.com/deepinsight/insightface/tree/master/RetinaFace

各顔に対して特徴量検出

取得した顔から特徴量認識はInsightFaceを使ってます

Openfaceという128次元取得のもの(正面から見た顔に対して、目じりの位置や鼻の頂点の位置等、64個の顔の中のパーツ配置をxy座標で表したもの)もあったのですが、顔の向きが正面前提で、動画のように顔の向きが一定ではない物に対しては認識が弱かったりしました

https://openface-api.readthedocs.io/en/latest/

あとpython2.6じゃないと動かなかったりで用意がめんどくさかったのも……

今回使うinsightfaceは512次元の特徴量を取得しています。512次元の中それぞれがどういった意味を持つかは未確認……
gitを見ると学習で3次元で顔の特徴位置推定やら色々やってみるたいです。


https://github.com/deepinsight/insightface

insightfaceを使う

insightfaceとretinaface、gitからcloneしても使えるんですが、8月頃からpipでも入れられるようになっているのでこれを使った方が楽です
https://pypi.org/project/insightface/

とりあえず導入手順

必要なモジュールも pip install -r requirments.txt でいれます

GPU使わない場合は[mxnet-cu90]を[mxnet]にしてください。

insightface本体はpip install だけで簡単に入ります

さっそく動くか試し

ここで取得できたnormed_embeddingが後工程に使う512次元特徴量になります。

ちなみに速度はGeForce GTX 1060で秒間3,4枚ほど
CPU実行では4秒ほどで1枚でした。
2080tiのような高スペックGPUではわかりませんが、リアルタイムでの動作はちょっときつそうです

全顔の特徴量に対してクラスタリング

そのままだと動画30フレームx50秒x映っている顔で数千枚の顔になってしまうので
クラスタリングで特徴量が近しい顔を同一人物の顔としてまとめます

クラスタリングの手法はk-meansや階層型クラスタリング等色々あるのですが
k-meansはクラスタ数をあらかじめ指定する必要があり、この動画に何人映っているのかわからないので、階層型クラスタリングで行います

クラスタリング結果確認

これまでの過程で個人識別はできるはずですが、クラスタリング結果が正しいか可視化して確認してみます
とりあえずhtmlで見やすいように整形して出力

クラスタリング結果で似ていると判定したものは同行に集めて表示しました

クラスタリング結果、ブレてる顔が多いなぁ…

上手くいくとこんな感じでまとまってくれます

上手くいった例
顔角度が異なったものも同一人物として推定、上手くいった例

綺麗にクラスタリングされていると各クラスタこうなってくれる
しかし実際にはきれいなものは一部だけで……

見切れてる画像で顔か怪しい

もはやこれだけ見ても顔なのかわからない

同一人物のはずが、カメラのブレと角度の所為か同一クラスタ扱いにはならなかったり

同一人物だが別のクラスタ扱いになってしまったパターン
同一人物だが、顔正面にカメラがあるために別のクラスタになったパターン

どういった分類になるのかわかってきたので、このデータを除外する方法考えます。

ゴミ除去

除外条件として下記を想定して削除します

  • 顔切り出したした際にサイズが小さいもの
  • クラスタ内を構成する顔数が少ないもの

除去した状態で再度クラスタリング結果確認

最終的にこれくらいの人数が顔認識できました。
53人…ですが同一人物で複数のクラスタになっていたり……

認識できた人物に表示して、とりあえず毎フレーム毎に顔に矩形を描いて連番画像として出力します。
クラスタ認識まで行かなかった除外や小サイズの顔は緑枠、クラスタリングで残った顔の人は赤枠をつけます。

53人と推定

さらに連番画像から動画に戻した結果がこれです。

映る角度によって別人クラスタにいなっていたりしますが、大きく映る顔に対しては割と分類してくれているようです

妙な例

左手を顔として認識してしまってます
ガラスに映る小さい顔まで認識しています、が小さすぎて顔特徴量が怪しいためにクラスタリングせず

ちなみに精度はこだわらず速度重視で同じような事を行うのであれば
DLIBで顔検出を行い、OpenCV+openfaceの128次元特徴量でも可能でしかも軽いです
あらかじめ検出したい人物の顔を登録しておき、カメラに映った時点でその人物の顔範囲に矩形描画まで行いた場合にはそちらが良さそうです。

About the author

grande_chien

Add Comment

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

By grande_chien

最近の投稿

アーカイブ

カテゴリー

タグクラウド

コーポレートサイト

メタ情報