質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.37%
OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

1回答

2860閲覧

ZeroDivisionError : float devision by zeroが解消できない

yumiwo

総合スコア5

OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2020/06/19 15:04

編集2020/06/20 03:33

こんにちは
自分で撮影した動画の重心を求めたいのですが、重心を計算するところで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を返していると予想されるフレーム付近を切り取ったりしてみました。
その場合は上手くコードが動いてくれるのですが、もっと良い解決策を知っている方いらっしゃれば教えてください。

参考記事1

参考記事2

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tiitoi

2020/06/19 15:17

動画の重心とはどういう意味でしょうか? cv2.moments() は cv2.findContours() で抽出された輪郭を渡すものであり、画像をそのまま渡す関数ではありません。
yymmt

2020/06/19 16:20

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 と入れて置けば同じ意味になると思います。
yumiwo

2020/06/19 16:26

tiitoiさんコメントありがとうございます。 言葉足らずでした。 動画に映りこんだ対象物の重心を求めたいです。 その場合は、cv2.moments ()を使用するで正しいですか?
yumiwo

2020/06/19 16:29 編集

yymmtさん コメントありがとうございます。
meg_

2020/06/20 01:04

エラーメッセージを載せてください。 「例外処理を行ったり、if文を書いたりしてみました」とのことなので、そのコードも載せてください。
yumiwo

2020/06/20 02:25

meg_さんコメントありがとうございます。 コード載せておきました。 お時間あれば見ていただけると嬉しいです。
meg_

2020/06/20 03:16

例外処理は関数の中に書くべきではないですか。
yumiwo

2020/06/20 03:34

meg_さんありがとうございます。 おっしゃる通りでした。 初歩的なところでたくさんミスがあり見づらいコードで申し訳ないです。 ご指摘ありがとうございます
tiitoi

2020/06/20 03:41

if 文を入れたバージョンでも cul_gravity_point() 内で float division by zero が出るのでしょうか?
kabayan55

2020/06/20 10:03

if 文を入れたバージョン、x,y= int(mu["m10"]/mu["m00"]) , int(mu["m01"]/mu["m00"]) をelse文に入れないと、分母が0になるケース(mu["m00"]=0)の場合にエラーになってしまうのではないでしょうか? if文の方にもmu["m00"]が0の場合の重心を求める式を書けば良いのではないかと思います。
yumiwo

2020/06/20 14:22

tiitoiさん cul_gravity_point()内でも同様にfloat division by zeroが出てきます。
yumiwo

2020/06/20 14:22

kabayan55さん コメントありがとうございます 早速試してみます!
guest

回答1

0

自己解決

動画によってエラーが出たり出なかったりだったため例外処理をしてコードを通しました。

投稿2020/07/01 10:32

yumiwo

総合スコア5

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問