##選択したアルゴリズム
####OpenCV2の組込み関数
- createBackgroundSubtractorMOG
##結果(一部)
他のフレーム画像は、__こちら__に掲載しました。
画像に続けて、__考察を掲載__しています。
前方走行車のテールランプが光った瞬間
数フレーム前に、テールランプが光り始めた後、1秒ほど光り*『続けている』*シーン
(光り__続けて__おり、__直前のフレームと同じ状態が継続している__ので、__黒く__消えている。)
(なぜ??)
前のフレームと比べて(ほとんど)変化していないはずの地上の設置物が、白く映っている。
(なぜ??)
前のフレームと比べて(ほとんど)変化していないはずの地上のレーン両端の設置物が、白く映っている。
(なぜ??)
前のフレームと比べて大きく変化しているはずの胸と肩が、白く映っていない。
(なぜ??)
前のフレームと比べて大きく変化しているはずの腕や手のひらが、白く映っていない。
(なぜ??)
前のフレームと比べて、位置や姿勢が激しく変化しているはずの人物が、白く映っていない。
(なぜ??)
前のフレームと比べて、位置や姿勢が激しく変化しているはずの人物が、白く映っていない。
(なぜ??)
前のフレームと比べて、位置や姿勢が激しく変化しているはずの人物が、白く映っていない。
シーンが切り替わった直後
似たシーンが続いた後
シーンが切り替わった直後
似たシーンが続いた後
##気づいたこと
- 直前のフレームと比較して、位置と形が大きく変わっている領域は、綺麗に白色表示された
- 上で白くなった部分も、1秒程度、前のフレームからの変化が乏しくなると、急速に黒色に塗り潰されていく
- 動いている部分に隣接する「動きのない」領域は、黒になる
「1」の例
- 速い速度で上下左右に平行移動している物体
- 早い速度で、回転したり、斜め方向や円・楕円運動で位置を変えている物体
- まったく異なるシーンに切り替わった直後 (画像全体が、直前のフレームとは様変わりしている)
「3」の例
- 人間の身体のうち、数秒間にわたって動いていない部位 (手は動いているが、腕や肩や胸は動いていない、など)
不思議な点
- 直前のフレームばかりか、過去数秒間に表示されたすべてのフレーム画像と比較して動いていない部分で、白く表示される領域があった。(例: F1レーズ会場の背景の看板の文字、レース会場の道路に設置されたフェンスや側溝)
- 直前のフレームばかりか、過去数秒間に表示されたすべてのフレーム画像と比較して、大きく動いている部分で、黒く表示される領域があった。(例: 滑走路を移動中の戦闘機の両翼や尾翼の縁の内部 (縁だけ、白い線で表示されていた)
なお、人物は、上記の一つ目に該当する領域が、複数の異なる動画で共通して多くみられた。
- 直前のフレームばかりか、過去数秒間に表示されたすべてのフレーム画像と比較して動いていない部分で、白く表示される領域があった。(例: F1レーズ会場の背景の看板の文字、レース会場の道路に設置されたフェンスや側溝)
上記の初見は、今回採用したOpenCV2のcreateBackgroundSubtractorMOGメソッドに特有のものなのだろうか。
アルゴリズム以外にも、モデル学習時に用いたデータも、関わっているかもしれない。(正解データの作成仕様など)
####アルゴリズムの出典論文
##実装コード
次のウェブサイトを参考にしました。
import numpy as np
import cv2
import argparse
from copy import copy
from copy import deepcopy
#(参考)https://pystyle.info/opencv-background-substraction/
# 動画ファイル名をコマンドライン引数から受け取る
parser = argparse.ArgumentParser(description='') #
parser.add_argument('--file_name')
args = parser.parse_args()
movie_file = args.file_name
cap = cv2.VideoCapture(movie_file)
#cap = cv2.VideoCapture("kawaguchi_haruna_nomu_cm.mp4")
wait_secs = int(1000 / cap.get(cv2.CAP_PROP_FPS))
model = cv2.bgsegm.createBackgroundSubtractorMOG()
while True:
ret, frame = cap.read()
frame_copy = frame.copy()
#frame_copy = frame.deepcopy()
if not ret:
break
mask = model.apply(frame_copy)
#cv2.imshow("Mask", mask)
#cv2.imshow("Original", frame)
#https://qiita.com/hibit/items/82de8422c7ec3a1aa774
#https://qiita.com/Makano/items/3148d568e4a523ee7cf8
#
mask = cv2.cvtColor(mask,cv2.COLOR_GRAY2BGR)
left_image = np.array(mask)
#left_image = left_image.astype('float32')
right_image = np.array(frame)
#right_image = right_image.astype('float32')
# 左右の画像の縦横サイズを揃える
height = right_image.shape[0]
width = right_image.shape[1]
resized_right_image = cv2.resize(right_image, (int(2.0*width), int(2.0*height)))
resized_left_image = cv2.resize(left_image, (int(2.0*width), int(2.0*height)))
merged_image = cv2.hconcat((resized_left_image, resized_right_image))
merged_height = merged_image.shape[0]
merged_width = merged_image.shape[1]
#resized_merged_image = cv2.resize(merged_image, (int(10.0*merged_width), int(10.0*merged_height)))
cv2.namedWindow("Window", cv2.WINDOW_NORMAL)
cv2.imshow("Window", merged_image)
#cv2.imshow("Window", resized_merged_image)
cv2.waitKey(wait_secs)
cap.release()
cv2.destroyAllWindows()
###実行コードの例
% python3 display_moving_objects_erase_background_success_2divided_window.py --file_name indian_dance.mp4