15
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

室内人数カウントシステムの開発

Last updated at Posted at 2022-08-24

はじめに

コロナ渦で室内の混雑状況を知りたい機会が増えたので,室内の人数を調査するシステムを作ってみようと思った。

概要

Yorov5とDeepsortを用いて,室内の人数をカウントするプログラムを作成した。また,室内の人数を取得,更新できるLINEボットを作成した。(おまけ)

手法

人数取得のおおまかな手法は以下の2つが考えられる

  1. 店内上部から店内を撮影し,その画像から物体検出によって人数を推論する(天井手法)
  2. 出入り口に設置したカメラの映像を用いて,トラッキングと物体検出によって,入店した人数と退店した人数から店内の人数を推論する(出入り口手法)

各手法のメリットとデメリット

天井手法

  • 画像推論なので処理が軽い → マシンパワーがいらない
  • 撮影時の画角内の人数が確実にわかる
  • 複雑な構造な部屋だと,カメラが複数台必要になる

出入り口手法

  • 出入り口の設置であるため部屋の構造に影響されない
  • 推論人数がずれた場合の処理が必要
  • 動画推論なので処理が重い → マシンパワーが必要

実装

今回はとりあえず出入り口手法を実装した。

技術スタック

  • Heroku
  • Flask(Python)
  • LINE Messaging API
  • SQLite
  • Deepsort(出入り口手法)
  • yorov5(出入り口手法)
  • Amazon Rekognition(天井手法)

出入り口手法

アーキテクチャ図は以下のようになっている。画像にはJetson nanoと書いてあるが,開発段階では自前のPCで代用している。
Untitled Diagram.drawio.png

ソースコードは,Yolov5 + StrongSORT with OSNetのリポジトリをクローンして利用する。このプログラムでは,人間の入室,退室判定ができないのでその部分を別途実装する。

入室,退室判定機能の実装

下の画像の様に動画内で境界線(部屋の出入口)を引く。物体検出によって得られたボックスの重心がフレームの前後で境界線をまたいだ場合その向きによって入店,退店を判定する。ここで,境界線と,フレーム前後のボックスの重心を結んだ線分が交差するとき,境界線をまたいだとみなす。

作成したプログラムの抜粋

# 2線分の交差判定
def crossing_detection(
    p1: Tuple[int, int], p2: Tuple[int, int], p3: Tuple[int, int], p4: Tuple[int, int]
) -> bool:
    tc1 = (p1[0] - p2[0]) * (p3[1] - p1[1]) + (p1[1] - p2[1]) * (p1[0] - p3[0])
    tc2 = (p1[0] - p2[0]) * (p4[1] - p1[1]) + (p1[1] - p2[1]) * (p1[0] - p4[0])
    td1 = (p3[0] - p4[0]) * (p1[1] - p3[1]) + (p3[1] - p4[1]) * (p3[0] - p1[0])
    td2 = (p3[0] - p4[0]) * (p2[1] - p3[1]) + (p3[1] - p4[1]) * (p3[0] - p2[0])
    return tc1 * tc2 < 0 and td1 * td2 < 0

2線分が交差しているかどうかを判定する関数

# 入か出かの判定(入->True, 出->False)
def enter_exit_detection(
    border_point1: Tuple[int, int],
    border_point2: Tuple[int, int],
    point: Tuple[int, int],
) -> bool:
    a = np.asarray(border_point1)
    b = np.asarray(border_point2)
    p = np.asarray(point)

    ab = b - a
    ap = p - a
    cross_product = np.cross(ap, ab)
    return cross_product > 0

ある点が,境界線の線分に対して右にあるか左にあるかを判定する関数。カメラの位置によってどっちが部屋の外かは変わるので,調整する必要がありそう。

これらの関数を利用して,各フレームごとに入退室判定を行う。また,画面上にはカウンタや境界線の表示を行っている。作成したプログラムはこのリポジトリのmytrack.pyにまとめている。

ezgif.com-gif-maker (1).gif

動画内の白い境界線をまたぐ方向によってカウンタが正しく動作していることがわかる。

LINEボットの作成(おまけ)

室内の人数を取得,更新できるLINEボットを作成した。ソースコードはこちら

今後の展望

  • 天井手法も実装したい(Amazon Recognitionを使えばすぐできそう)
  • 今回実装した出入り口手法の推論をサーバー上で行う → ローカルのマシンコストや拡張性が高まりそう,AWSの料金はすごく高そう,,
  • 出入口カメラを赤外線人感センサにすることで,プライバシー問題を解決したい(RNNで波形を学習することで入室か退室かの判定ができるかな?)

参考文献

15
7
0

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
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?