少し前の状態の背景画像と、新たに何かが入ってきた状態の2つの画像の差を取ることで物体検出する手法を背景差分法といいます。
よくある利用事例として、固定カメラを使って来店者のカウント、自動車などの交通流量カウントなどに応用されます。
しかし、厳密には、物体の画像を取得した場合、影が存在するので単純な2つの画像の引き算ではうまく物体のみを検知できないケースがあります。そのため、様々なアルゴリズムが提案され、OpenCVでは以下の3つのアルゴリズムが用意されているので試しに実装してみます。
- BackgroundSubtractorMOG
- BackgroundSubtractorMOG2
- BackgroundSubtractorGMG
実装サンプルコード(BackgroundSubtractorMOG)
チュートリアルのサンプルコードは動画を使っていますが静止画でも動きますので以下のようなコードで実装してみました。
# -*- coding: UTF-8 -*-
import cv2
if __name__ == '__main__':
# 画像の読み込み
img_src1 = cv2.imread("background_image.jpg", 1)
img_src2 = cv2.imread("frontground_image.jpg", 1)
fgbg = cv2.bgsegm.createBackgroundSubtractorMOG()
fgmask = fgbg.apply(img_src1)
fgmask = fgbg.apply(img_src2)
# 表示
cv2.imshow('frame',fgmask)
# 検出画像
bg_diff_path = './diff.jpg'
cv2.imwrite(bg_diff_path,fgmask)
cv2.waitKey(0)
cv2.destroyAllWindows()
チュートリアルの実装では実行時にエラーが出る
OpenCVのチュートリアルでは
fgbg = cv2.createBackgroundSubtractorMOG()
となっていますが、背景差分のアルゴルズムが contrib に移動されたので
fgbg = cv2.bgsegm.createBackgroundSubtractorMOG()
と実装する必要があります。
contrib のインストール
cv2.bgsegm.createBackgroundSubtractorMOG() としていてもエラーが出る場合は、contrib がインストールされていませんのでOpenCVのバージョンなど環境にあわせて追加してください。
>pip install opencv-contrib-python
入力画像
2017年必須のオフィス玩具と言われていたハンドスピナーにマウスを追加してみます。
実行結果
マウスだけが抽出されました。
光の加減でハンドスピナーの位置に白いドットが微妙にあるけど…
参考資料
https://docs.opencv.org/3.4.0/db/d5c/tutorial_py_bg_subtraction.html
http://answers.opencv.org/question/94448/module-cv2-has-no-attribute-createbackgroundsubtractormog/