RaspberryPi ラズパイ(Python)

ラズパイとOpenCVで動体検知

どうも。まっきーです。

監視カメラの準備段階として、動体検知を勉強をしました。

自分なりにまとめてみたので動体検知をやろうと思っている方の参考になればと思います。

本記事の内容
  • 動体検知の流れ(コードと画像で解説)
  • 動体検出方法①
  • 動体検出方法②

動体検知の流れ

基本の動体検知用のソースコードを置いておきます。

動画の名前を変えるorカメラモードにするだけで試せます。

動体検知ソースコード

以下、動体検知の流れです。

  1. 画像をグレースケールに変換
  2. 前フレームを保存
  3. 移動平均を求める
  4. 現在とのフレームと移動平均の差を計算する
  5. 閾値を設定してフレームを2値化(黒と白に分ける)
  6. 閾値処理された画像上の輪郭を見つける
  7. 輪郭を描写する

最終的に図のように、輪郭が描写できます。以下、詳しく解説していきます。

画像をグレースケールに変換

前フレームを保存

前のフレームを保存します。

移動平均を求める

グレースケールの画像を前画像と比較して移動平均というものを求めています。

累算器画像とは前のフレームのことですね。

alpha は,更新速度(どのくらいの早さで,以前の画像を「忘れる」か)を調節します。alphaの値を調節することでどれだけ残像を残すかを変えられます。

少しわかりずらいかもしれませんが、alphaの値を変えると残像が大きくなっているのが確認できると思います。

現在とのフレームと移動平均の差を計算する

動体フレーム = |現在のフレーム - 背景|

上記の式により、現在のフレームから背景を引いた差分frameDeltaを求めます。

閾値を設定してフレームを2値化(黒と白に分ける)

カラー画像やモノクロ(グレースケール)画像など、複数の色や明るさで表現された画像を、黒と白の2色だけの画像に変換することを二値化と言います。一般的に「しきい値」という値を用いて、それより明るい点を白(255)、暗い色を黒(0)に置換します。二値化した画像の利用目的に応じ、この「しきい値」を適切な値に設定することが大切になります。(参考Python+OpenCVを利用した二値化処理

閾値処理のタイプは以下の5種類あります。使用しているのはBINARYです。

  • cv2.THRESH_BINARY
  • cv2.THRESH_BINARY_INV
  • cv2.THRESH_TRUNC
  • cv2.THRESH_TOZERO
  • cv2.THRESH_TOZERO_INV

実際に閾値の値を変更することでどれぐらいの感度にするかを調節できます。

閾値=5の時
閾値=30の時

閾値の値を大きくしすぎると、見落とすものも出てきてしまいます。必要に応じて調節する必要がありますね。

閾値処理された画像上の輪郭を見つける

先ほどの画像を見ていただければわかるかと思いますが、OpenCVの輪郭検出は,黒い背景から白い物体の輪郭を検出すると仮定しています。物体は白で背景は黒です。

cv2.CHAIN_APPROX_SIMPLEは輪郭の検出方法を指定しています。このフラグを設定すると、下図の右側のように輪郭を検出します。

これをすることにより、メモリを節約できます!

cv2.RETR_EXTERNALフラグ等の輪郭の階層情報の説明はややこしいので、詳しく知りたい方はOpenCVのチュートリアルを見てください。

輪郭を描写する

これで最初のように、動いている人の輪郭を描写できます。

動体検出方法

色々調べていると、個人的な監視カメラに使うための動体検出方法で参考になったものが2つありましたので、2つとも紹介します。2つのソースコードで大きく異なる点は強調されている動体を検知する際の判定部分です。

ラズパイカメラで行うことを前提としておりますので注意してください。USBカメラでもできるとは思いますが、保証できません。すみません。

動体検出方法① 面積を用いる方法

cv2.contourArea()を用いて、輪郭の面積を求めます。イメージとしては下の写真のような感じです。

動いた面積のしきい値を自分で設定して、if文を作り、動体を検知する仕組みです。

上の画像はかなり大きな面積なので1万とかいう値になっていますが、実際の防犯カメラは遠くからの撮影となるので1000ぐらいの値でいいと思います。

この方法は比較的わかりやすかったです。

動体検出方法② ピクセルの誤差を用いる方法

この処理方法はとても面白いなと思いました。二値化処理した画像のピクセル値に変化があった場合動体を検知するという仕組みです。以下の画像を見てください。

このような変化の程度をMOTION_FACTOR_THという閾値を超えるか超えないかで判断しています。

監視カメラは基本的には定点で用いられると思うのでこの方法も便利ですね。

2種類の方法どちらも動体検知ができるので好きな方を使って監視カメラを作っていきたいと思います。

おわりに

いかがでしたでしょうか。OpenCVを使えば、簡単に動体検知をすることができます。

この機能を応用すれば自宅用監視カメラも自作できますね!ぜひ試してみてください!

次回はオリジナル監視カメラの作成に挑戦してみたいと思います。

参考

OpenCVを利用して動画(カメラ)から動体検知をする方法について

Raspberry Piで最強の防犯カメラを作ってみる(動画記録・配信、動体検知・Line通知、顔検知・顔認証、Alexa搭載)[3/6]

Python+OpenCVとWebカメラを使って動体検知する話

RaspberryPiでWEBカメラを使ってOpenCVで動体検知な監視カメラをつくってみた

-RaspberryPi, ラズパイ(Python)

© 2020 まきろぐ Powered by AFFINGER5