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

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

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

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

Python

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

Q&A

解決済

1回答

2108閲覧

動画ファイルを出力したい

退会済みユーザー

退会済みユーザー

総合スコア0

OpenCV

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

Python

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

0グッド

0クリップ

投稿2017/10/13 07:24

###前提・実現したいこと
https://github.com/akisato-/pySaliencyMap

上記のサイトにて公開されている、
Webカメラ映像をSaliencyMap化するソースコードに関して質問させていただきます。

こちらを動画ファイルとして保存したいと考えております。
しかし、実行しても以下のエラーが表示されてしまい、
出来上がった「output.avi」を再生することができません。
(ファイルサイズが0KBになっています)

どうしたら、正しく動画を出力することができますか?

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

OpenCV Error: Assertion failed (image->depth == 8) in CvVideoWriter_FFMPEG_proxy::writeFrame, file D:\Build\OpenCV\opencv-3.3.0\modules\videoio\src\cap_ffmpeg.cpp, line 272 Traceback (most recent call last): File "main_webcam.py", line 33, in <module> out.write(frame) cv2.error: D:\Build\OpenCV\opencv-3.3.0\modules\videoio\src\cap_ffmpeg.cpp:272: error: (-215) image->depth == 8 in function CvVideoWriter_FFMPEG_proxy::writeFrame

###該当のソースコード

python

1 2import cv2 3import matplotlib.pyplot as plt 4import pySaliencyMap 5import numpy as np 6 7if __name__ == '__main__': 8 9 capture = cv2.VideoCapture(0) 10 11 while(True): 12 13 retval, frame = capture.read() 14 15 frame_size = frame.shape 16 frame_width = frame_size[1] 17 frame_height = frame_size[0] 18 sm = pySaliencyMap.pySaliencyMap(frame_width, frame_height) 19 20 saliency_map = sm.SMGetSM(frame) 21 22 cv2.imshow('Input image', cv2.flip(frame, 1)) 23 cv2.imshow('Saliency map', cv2.flip(saliency_map, 1)) 24 25 fourcc = cv2.VideoWriter_fourcc(*'XVID') 26 out = cv2.VideoWriter('output.avi',fourcc, 20.0, (1280,720)) 27 28 while(capture.isOpened()): 29 retval, frame = capture.read() 30 31 if retval==True: 32 frame = cv2.flip(saliency_map, 1) 33 34 out.write(frame) 35 36 cv2.imshow('frame',frame) 37 if cv2.waitKey(1) & 0xFF == ord('q'): 38 break 39 else: 40 break 41 42 if cv2.waitKey(1) & 0xFF == ord('q'): 43 break 44 45 cv2.destroyAllWindows()

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

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

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

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

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

LouiS0616

2017/10/13 08:46

out.write() 直前でのframeのshapeはどうなっていますか。
guest

回答1

0

ベストアンサー

走らせていないですが、LouiS0616さんのおっしゃるようにout.write(frame)が怪しいですね。

もう少し戻るとwhile の二重構造で、二個目のwhileはカメラが読み込めるなら~となっていますが、実際のところカメラ画像をretval, frame = capture.read() で拾っても、その後のframe = cv2.flip(saliency_map, 1)で常に上書きされてしまうように見えます(どういうことをしたいかはとりあえず置いておきます)。

つまり、frameの中身は、saliency_mapをフリップしたものが常に入りますね。もう少し戻ると、
saliency_map = sm.SMGetSM(frame)とあります。whileの1つ目のカメラ画像を何らかの処理したもの、と思います。ここで、sm.SMGetSMの正体を調べると、sm = pySaliencyMap.pySaliencyMap(frame_width, frame_height)とありますので、pySaliencyMapのSMGetSMsm.SMGetSMの正体ですね。

さらに、さかのぼってモジュール発行元のGITclass pySaliencyMapSMGetSMreturnの値を追うと、以下略normalizedSM2 = normalizedSM.astype(np.float32)に突き当たります。

つまり、out.write(frame)の中身はfloat32だということになります。
ここでエラーに戻ると、

cv2.error: D:\Build\OpenCV\opencv-3.3.0\modules\videoio\src\cap_ffmpeg.cpp:272: error: (-215) image->depth == 8 in function CvVideoWriter_FFMPEG_proxy::writeFrame

depth == 8、細かいことは書いてないですが、int8ならいけそうですね。int8は0~255の値です。ところが、numpy.float32は浮動小数点ですので、なんとかしてint8にしてやらないといけませんね。

どんな値がfloat32に収まっているか分かりませんが、ここが参考になると思います。

どうにもならない場合には、float32の値をコメント欄につけてください。

投稿2017/10/13 10:21

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

退会済みユーザー

退会済みユーザー

2017/10/13 13:56

ご回答ありがとうございます。 また、参考となるURLまで提示していただき、非常に助かります。 現段階では解決しておりませんが、頂いたヒントを参考に一つ一つ解いていこうと思います。
退会済みユーザー

退会済みユーザー

2017/10/13 14:04 編集

画像はx,y座標毎にint8(0~255)が入るのですが、これに多分、float32(32bitの浮動小数点)が入っているから動画に出来ないよ、ということだと思います。なので、numpyのfloat32をnumpyのint8に変換する関数を探せばOKです。 場所は out.write(frame)の部分ですよ、frameの中身がfloat32なのでframeの中身をint8にということです。 ※実際に走らせてないのでたぶんの話です。
退会済みユーザー

退会済みユーザー

2017/10/13 15:03

返信ありがとうございます。 アドバイス通りにfloat32をint8に変換した結果、無事にout.write(frame)でエラーが起こらなくなりました。 しかし、実行時に表示されるウィンドウの状態が、 「Input image」「Saliency map」「frame」いずれも真っ黒な画面が表示されてしまいました。 どうやら、while(capture.isOpened()): の中身が無限ループしているようです。 次はこちらを解決しようと思います。 関数変換に関するご助言、大変役に立ちました。 ありがとうございます。
退会済みユーザー

退会済みユーザー

2017/10/13 18:38 編集

全ての環境ではないようですが、カメラの起動に1コマかかるのか、retval, frame = capture.read()の1回目だけは真っ黒が映るようです。なので、はじめのwhileの外で一度retval, frame = capture.read()をして、はじめのwhileにwhile retvalのような感じにすればよいと思います。その代わり、2つ目のwhileは更新前の画像をひたすら無限ループするようになっているので、2つめのwhileの中でつどカメラの画像を取り直すか2つ目のwhileをとっぱらうか、そういう対応が良いと思います。 聞くよりやった方が覚えると思いますので、細かいコードはuppさんで書いてくださいね。
退会済みユーザー

退会済みユーザー

2017/10/26 03:10

先日、こちらの問題を無事解決することができました。 ループの中に以下の fourcc = cv2.VideoWriter_fourcc(*'XVID') out = cv2.VideoWriter('output.avi',fourcc, 20.0, (1280,720)) が入っているなど、理解が足りていない部分が多くあり、非常に勉強になりました。 迅速な対応とわかりやすい解説、ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問