OpenCVのBackgroundSubtractorクラスを使った動画の背景差分

概要

この記事ではaviファイルの映像から動いている物体のみを描写するプログラムについて紹介しています。 OpenCVのBackgroundSubtractorクラスは、動画やリアルタイムカメラフィードから背景と前景を分離するために使用されます。 これは、監視カメラの映像から人や車などの動く物体を検出する際や、ビデオチャットで背景をブラーにするなどのアプリケーションで役立ちます。 BackgroundSubtractorは、各ピクセルの時間的な変化を学習し、それに基づいて背景と前景を分離します。 これにより、動きのある物体(前景)を背景から効果的に分離することができます。

出力結果

動画ファイルダウンロード:opencv_background_subtraction_video.avi

プログラム全体

# 解説1 import cv2 #解説2 # ビデオファイルを読み込む cap = cv2.VideoCapture('video.avi') # フレーム間の待機時間を計算する(ミリ秒単位) wait_secs = int(1000 / cap.get(cv2.CAP_PROP_FPS)) #解説3 # 背景差分を計算するためのモデルを作成する model = cv2.createBackgroundSubtractorMOG2() # ビデオの終わりまでループする while True: # ビデオからフレームを読み込む ret, frame = cap.read() # フレームがない場合はループを抜ける if not ret: break # フレームから背景差分マスクを計算する mask = model.apply(frame) # 背景差分マスクを表示する cv2.imshow("Mask", mask) # 指定した時間だけ待つ cv2.waitKey(wait_secs) #解説4 # ビデオファイルを解放する cap.release() # すべてのウィンドウを閉じる cv2.destroyAllWindows()

解説

解説1:OpenCVのインポート

import cv2

この行はOpenCVライブラリをインポートしています。OpenCVは、画像処理やコンピュータビジョンのタスクを行うための強力なライブラリで、Pythonからも利用できます。今回のプログラムでは、ビデオファイルからフレームを取り出し、背景差分を計算するためにこのライブラリを使います。

解説2:ビデオファイルの読み込みとフレームレートに基づく待機時間の計算

# ビデオファイルを読み込む cap = cv2.VideoCapture('video.avi') # フレーム間の待機時間を計算する(ミリ秒単位) wait_secs = int(1000 / cap.get(cv2.CAP_PROP_FPS))

この部分では、ビデオファイルを読み込み、フレーム間の待機時間を計算しています。

cv2.VideoCapture('video.avi')はビデオファイルを読み込むためのオブジェクトを生成しています。ここで指定するファイル名は、読み込みたいビデオファイルの名前に変更する必要があります。

cap.get(cv2.CAP_PROP_FPS)は、読み込んだビデオのフレームレート(1秒間に表示されるフレームの数)を取得します。このフレームレートを基にして、各フレーム間の待機時間をミリ秒単位で計算します。

解説3:背景差分の計算と表示

# 背景差分を計算するためのモデルを作成する model = cv2.createBackgroundSubtractorMOG2() # ビデオの終わりまでループする while True: # ビデオからフレームを読み込む ret, frame = cap.read() # フレームがない場合はループを抜ける if not ret: break # フレームから背景差分マスクを計算する mask = model.apply(frame) # 背景差分マスクを表示する cv2.imshow("Mask", mask) # 指定した時間だけ待つ cv2.waitKey(wait_secs)

この部分では、背景差分を計算し、それを表示しています。

cv2.createBackgroundSubtractorMOG2()は背景差分を計算するためのモデルを作成します。背景差分は、ビデオ内で物体が動いている部分を検出するために使用されます。それぞれのフレームに対してモデルを適用することで、そのフレームの背景差分マスクを計算します。

cap.read()はビデオから次のフレームを読み込むメソッドです。フレームが正常に読み込まれると、retはTrueになり、frameにそのフレームのデータが格納されます。フレームがない場合(ビデオの終わりなど)、retはFalseになるため、ループから抜け出します。

cv2.imshow("Mask", mask)は背景差分マスクを表示するためのメソッドで、ウィンドウのタイトルを"Mask"とし、そのウィンドウに背景差分マスクを表示します。

cv2.waitKey(wait_secs)は指定した時間(ミリ秒単位)だけプログラムの実行を停止します。これは、ビデオを正しいフレームレートで表示するために必要です。

解説4:リソースの解放

# ビデオファイルを解放する cap.release() # すべてのウィンドウを閉じる cv2.destroyAllWindows()

この部分では、ビデオファイルを解放し、開いたウィンドウを全て閉じています。

cap.release()はビデオファイルを解放するためのメソッドです。これは、ビデオファイルを開いたままにしておくとリソースを無駄に消費してしまうため、ビデオの処理が終わったら必ず実行する必要があります。

cv2.destroyAllWindows()は、プログラムで開いた全てのウィンドウを閉じるためのメソッドです。これにより、プログラムが終了したときにウィンドウが残らないようにします。

追記:この記事の動画ではThe Imaging Source社 DFK33UX264とICCaptureを使用しています