こんにちは
自分で撮影した動画の重心を求めたいのですが、重心を計算するところでZeroDivisionErrorが発生します。
python3
1imgs = [] 2front_imgs = [] 3cap = cv2.VideoCapture(video_path) 4kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(10,10)) 5fgbg = cv2.createBackgroundSubtractorMOG2(detectShadows = False) 6 7for i in tqdm.tqdm(range(int(cap.get(cv2.CAP_PROP_FRAME_COUNT)))): 8 ret, frame = cap.read() 9 fgmask = fgbg.apply(frame) 10 fgmask = cv2.morphologyEx(fgmask, cv2.MORPH_OPEN, kernel) 11 imgs.append(frame) 12 front_imgs.append(fgmask) 13cap.release() 14imgs = np.array(imgs) 15front_imgs = np.array(front_imgs) 16def cul_gravity_point(img): 17 mu = cv2.moments(img, False) 18 x,y= int(mu["m10"]/mu["m00"]) , int(mu["m01"]/mu["m00"]) 19 return x,y 20def cul_area_size(img): 21 return np.sum(np.sign(img)) 22 gravity_coordinate = np.array([cul_gravity_point(front_imgs[i]) for i in range(len(front_imgs))],dtype=np.dtype("uint32")) 23 area = np.array([cul_area_size(front_imgs[i]) for i in range(len(front_imgs))])
対策として、例外処理を行ったり、if文を書いたりしてみましたが動画によってエラーが消えたり消えなかったりしました。
#if文を入れたバージョンです def cul_gravity_point(img): mu = cv2.moments(img, False) x,y= int(mu["m10"]/mu["m00"]) , int(mu["m01"]/mu["m00"]) if mu["m00"] == 0: return float("none") else: return x,y def cul_area_size(img): return np.sum(np.sign(img)) gravity_coordinate = np.array([cul_gravity_point(front_imgs[i]) for i in range(len(front_imgs))],dtype=np.dtype("uint32")) area = np.array([cul_area_size(front_imgs[i]) for i in range(len(front_imgs))])
#例外処理をしたバージョンです def cul_gravity_point(img): try: mu = cv2.moments(img, False) x,y= int(mu["m10"]/mu["m00"]) , int(mu["m01"]/mu["m00"]) return x,y except ZeroDivisionError: print("ZeroDivisionError!!") def cul_area_size(img): try: return np.sum(np.sign(img)) gravity_coordinate = np.array([cul_gravity_point(front_imgs[i]) for i in range(len(front_imgs))],dtype=np.dtype("uint32")) area = np.array([cul_area_size(front_imgs[i]) for i in range(len(front_imgs))]) except ZeroDivisionError: print("ZeroDivisionError!!!")
また例外処理をした際に、ZeroDivisionErrorを返していると予想されるフレーム付近を切り取ったりしてみました。
その場合は上手くコードが動いてくれるのですが、もっと良い解決策を知っている方いらっしゃれば教えてください。
動画の重心とはどういう意味でしょうか?
cv2.moments() は cv2.findContours() で抽出された輪郭を渡すものであり、画像をそのまま渡す関数ではありません。
https://docs.opencv.org/master/d8/d23/classcv_1_1Moments.html
を見ると、画素値が0以上の整数を取るとした場合、array(x,y)の値は全て0ということになります。その場合
if mu["m00"] == 0.0:
x = (img.shape[0] - 1)/2
y = (img.shape[1] - 1)/2
と入れて置けば同じ意味になると思います。
tiitoiさんコメントありがとうございます。
言葉足らずでした。
動画に映りこんだ対象物の重心を求めたいです。
その場合は、cv2.moments ()を使用するで正しいですか?
yymmtさん
コメントありがとうございます。
エラーメッセージを載せてください。
「例外処理を行ったり、if文を書いたりしてみました」とのことなので、そのコードも載せてください。
meg_さんコメントありがとうございます。
コード載せておきました。
お時間あれば見ていただけると嬉しいです。
例外処理は関数の中に書くべきではないですか。
meg_さんありがとうございます。
おっしゃる通りでした。
初歩的なところでたくさんミスがあり見づらいコードで申し訳ないです。
ご指摘ありがとうございます
if 文を入れたバージョンでも cul_gravity_point() 内で float division by zero が出るのでしょうか?
if 文を入れたバージョン、x,y= int(mu["m10"]/mu["m00"]) , int(mu["m01"]/mu["m00"]) をelse文に入れないと、分母が0になるケース(mu["m00"]=0)の場合にエラーになってしまうのではないでしょうか?
if文の方にもmu["m00"]が0の場合の重心を求める式を書けば良いのではないかと思います。
tiitoiさん
cul_gravity_point()内でも同様にfloat division by zeroが出てきます。
kabayan55さん
コメントありがとうございます
早速試してみます!
回答1件
あなたの回答
tips
プレビュー