前提・実現したいこと
動画からフレーム画像を取得し、最初のフレームを背景画像としてそれ以降の画像を背景差分し取得します。
動画開始から30フレーム程度は背景画像と全く同じ画像となってしまう(複数動画の処理、背景画像と全く同じ画像となるフレームが一定ではない)ため、その後の処理(重心検出)が通りません。
背景差分後の画像に物体が映ったときのフレーム以降でその後の処理を行わせる、何フレーム目から物体が映っているのかを調べるためには、どのような方法があるのかご教示いただきたく存じます。
###追記
該当ソースコードの修正、画像、エラーコードを追加しました。
画像は
一枚目 背景画像とする画像
二枚目 物体の映った画像(26フレーム目)
三枚目 物体が映っていないときの背景差分後の画像
四枚目 物体が映ったときの背景差分後の画像(26フレーム目)
となっています。
改めて、解決したい課題は
物体が映ったフレーム以降から重心検出の処理を行わせたい
というものです。
私の解釈では、三枚目の画像のようなときは重心検出ができなくてエラーになっているので(そもそもここが間違っていますか?)、物体の映った四枚目のような画像から重心検出を行うことができれば問題なく実行できると考えています。
物体の映った画像以降から処理を行うためにはどのような手段があるのかを探しています。
ちなみに重心検出を行う理由は物体の座標を取得するためです。
該当のソースコード
import cv2 import sys import numpy as np import glob import os video_path='C2278.mp4' #動画ファイル読込 cap=cv2.VideoCapture(video_path) if not cap.isOpened(): #正常に読み込めたのかチェック print('失敗') sys.exit() digit = len(str(int(cap.get(cv2.CAP_PROP_FRAME_COUNT)))) n= 0 while True: #read()でフレーム画像が読み込めたかを示すbool、フレーム画像の配列ndarrayのタプル is_image,frame_img=cap.read() if is_image: #画像を保存 cv2.imwrite("img"+str(n).zfill(digit)+".png",frame_img) #グレースケール画僧の読み込み im1=cv2.imread('img000.png',0) im2= cv2.cvtColor(frame_img, cv2.COLOR_BGR2GRAY) #背景差分 fgbg=cv2.bgsegm.createBackgroundSubtractorMOG() fgmask=fgbg.apply(im1) fgmask=fgbg.apply(im2) #メディアンフィルター th=cv2.medianBlur(fgmask,15) # 画像を保存 cv2.imwrite('threshold'+str(n).zfill(digit)+'.png',th) #モーメント関数で3次までのモーメントを取得 mu=cv2.moments(th) #図心を出す。 x,y= int(mu["m10"]/mu["m00"]) , int(mu["m01"]/mu["m00"]) print([x,y]) else: # フレーム画像が読込なかったら終了 break n += 1 cap.release()
###エラーコード
--------------------------------------------------------------------------- ZeroDivisionError Traceback (most recent call last) <ipython-input-4-a8ed6c71b0f4> in <module> 44 45 #図心を出す。 ---> 46 x,y= int(mu["m10"]/mu["m00"]) , int(mu["m01"]/mu["m00"]) 47 print([x,y]) 48 else: ZeroDivisionError: float division by zero
回答1件
あなたの回答
tips
プレビュー