Edited at

背景差分で物体抽出(画像比較)

少し前の状態の背景画像と、新たに何かが入ってきた状態の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


入力画像

background_image.jpg

background_image.jpg

2017年必須のオフィス玩具と言われていたハンドスピナーにマウスを追加してみます。

frontground_image.jpg

frontground_image.jpg


実行結果

diff.jpg

diff.jpg

マウスだけが抽出されました。

光の加減でハンドスピナーの位置に白いドットが微妙にあるけど…:sweat_smile:


参考資料

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/