やること
14-9では2枚の画像の差分を検出して間違い探しを解きました。
これを動画に適用すると、動いているものだけを検出することができます。今回は画像差分を用いて鮭の遡上を監視してみましょう。
実行環境
WinPython3.6をおすすめしています。
WinPython - Browse /WinPython_3.6/3.6.7.0 at SourceForge.net
Portable Scientific Python 2/3 32/64bit Distribution for Windows
Google Colaboratoryが利用可能です。
Google Colab
引用
こちらの動画の一部を拝借しました。感謝申し上げます。
これを入力します。
pip
必要なパッケージをインストールします。
pip install opencv-python
pip install opencv-contrib-python
pip install matplotlib
ソースコード
動画の処理なのにこんなに短いんです。動画を1フレームずつ読み込んで、最新の4枚を見比べて差分を取っていきます。差分領域のうち、面積が一定以上のものに矩形を引きます。
import cv2
import matplotlib.pyplot as plt
#=============================
# パラメータ
#=============================
#動画
movie_path = '14-17_movie.mp4'
#=============================
# 画像表示関数
#=============================
def show(img):
plt.figure(figsize=(10, 10))
plt.imshow(img, vmin = 0, vmax = 255)
plt.show()
plt.close()
print()
#=============================
# 処理
#=============================
#動画読み込み
video = cv2.VideoCapture(movie_path)
#画像差分の準備
fgbg = cv2.bgsegm.createBackgroundSubtractorMOG(history=4)
#繰り返し処理
while(video.isOpened()):
#フレームを取得
ret, frame = video.read()
#フレームがある場合
if ret == True:
#差分マスクの計算
fgmask = fgbg.apply(frame)
#輪郭検出
contours, _ = cv2.findContours(fgmask, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
#最小面積で選別
contours = [contour for contour in contours if cv2.contourArea(contour) > 200]
#すべての輪郭に矩形を引く
for contour in contours:
x, y, w, h = cv2.boundingRect(contour)
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 0, 255), 2)
#表示
show(frame)
#
frame_before = frame
else:
break
video.release()
実行すると、動く物体に矩形が引かれた画像が次々と表示されます。色がおかしいのはOpencv先生の仕様なので気にしないでください。
動画に戻す
これをがんばって動画に戻してやると、こうなります。
短いコードでしたが、及第点じゃないでしょうか!