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

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

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

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

1384閲覧

OpenCVで動体検知をかけたいです

suzukill

総合スコア1

OpenCV

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/01/24 05:17

編集2021/03/04 06:07

前提・実現したいこと

OpenCVで録画した映像に動体検知をかけるコードを作っています。
フレーム間差分法で閾値以上の差分があったシーンを指定のファイルに保存していきます。
画像の保存まで問題なくできるのですが動画を最後まで読み込む(?)とpythonの応答がなくなってしまい、毎回pythonを強制終了しなければならないです。
どうすればよいでしょうか。

発生している問題・エラーメッセージ

error: OpenCV(4.0.1) C:\ci\opencv-suite_1573470242804\work\modules\imgproc\src\resize.cpp:3784: error: (-215:Assertion failed) !ssize.empty() in function 'cv::resize'

該当のソースコード

python

1import cv2 2# 保存パスの指定 3save_path = "保存パス" 4def main(): 5 # 映像の取得". 6 cap = cv2.VideoCapture("映像のパス") 7 # フレームの初期化 --- (*1) 8 img1 = img2 = img3 = get_image(cap) 9 # 閾値の設定 10 th = 70 11 num = 1 12 while True: 13 ret, frame = cap.read() 14 if not ret: 15 break 16 # Enterキーが押されたら終了 17 if cv2.waitKey(1) == 13: break 18 # 差分を調べる --- (*2) 19 diff = check_image(img1, img2, img3) 20 # 差分がthの値以上なら動きがあったと判定 --- (*3) 21 cnt = cv2.countNonZero(diff) 22 if cnt > th: 23 print("動体を検出") 24 cv2.imshow('PUSH ENTER KEY', img3) 25 # 閾値以上の写真を画像として保存 --- (*4) 26 cv2.imwrite(save_path + str(num) + ".jpg", img3) 27 num += 1 28 else: 29 cv2.imshow('PUSH ENTER KEY', diff) 30 # 比較用の画像を保存 --- (*5) 31 img1, img2, img3 = (img2, img3, get_image(cap)) 32 # 後始末 33 cap.release() 34 cv2.destroyAllWindows() 35 36# 画像に動きがあったか調べる関数 37def check_image(img1, img2, img3): 38 # グレイスケール画像に変換 --- (*6) 39 gray1 = cv2.cvtColor(img1, cv2.COLOR_RGB2GRAY) 40 gray2 = cv2.cvtColor(img2, cv2.COLOR_RGB2GRAY) 41 gray3 = cv2.cvtColor(img3, cv2.COLOR_RGB2GRAY) 42 # 絶対差分を調べる --- (*7) 43 diff1 = cv2.absdiff(gray1, gray2) 44 diff2 = cv2.absdiff(gray2, gray3) 45 # 論理積を調べる --- (*8) 46 diff_and = cv2.bitwise_and(diff1, diff2) 47 # 白黒二値化 --- (*9) 48 _, diff_wb = cv2.threshold(diff_and, 30, 255, cv2.THRESH_BINARY) 49 # ノイズの除去 --- (*10) 50 diff = cv2.medianBlur(diff_wb, 5) 51 return diff 52 53# 映像から画像を取得する 54def get_image(cap): 55 img = cap.read()[1] 56 img = cv2.resize(img, (600, 400)) 57 return img 58main()

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2021/01/29 23:24

動画の長さはどれくらいでしょうか?少なくとも短い動画(~10秒)であればうまく動きました。 処理が重すぎる可能性がありますので、 if cv2.waitKey(1) == 13: break # 1[ms]待つ を if cv2.waitKey(1) == 13: break # 20[ms]待つ にして様子を見ていただけますか?
suzukill

2021/03/04 06:06

返信が遅れて大変申し訳ございません。そしてご回答ありがとうございます。 基本的に10分の動画に行っていましたが、10秒ほどの動画でも最後に固まってしまいます。 if cv2.waitKey(20) == 13: break に変更してみましたが、 うまくいかないです。
guest

回答1

0

ベストアンサー

要は,ココ↓でエラーになっているという話ですよね.

img = cv2.resize(img, (600, 400))

既に動画の末尾に達していた(もうread()で読めるフレームが無かった)場合,1行上の

img = cap.read()[1]

の結果として img が空っぽになるからですよね.

何やらmainのwhileループの先頭でも cap.read() を行ってますので,このループの一周で2回のフレーム読み出しが起こるように見えます.
で,そのうちの1回目の側にしかチェックが入っていない様子.

纏めると,「末尾に達したら終了」という処理の組み方自体が間違っているのだと思います.

投稿2021/03/04 06:25

fana

総合スコア11658

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

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

suzukill

2021/03/04 06:44

回答ありがとうございます。 映像から画像を取得する部分に「末尾に達したら終了」のコードを追加すればいいということでしょうか。
fana

2021/03/04 07:35 編集

ループ内で cap.read() を2回実施するのは,行いたい処理の意図と異なるだろうと思うので,そこから解消すべきではないでしょうか. 例えば, ・get_imageを,cap.read()の結果をちゃんと見て末尾判定を行うようにする.例えば,末尾に達していたら空のimgをそのまま返す ということにすれば, ・既存のwhile内先頭で行っている cap.read() を廃止し, ・その場所に img1, img2, img3 = (img2, img3, get_image(cap)) の処理を移して,img3を見て末尾判定する とか.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問