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

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

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

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

Python 2.7

Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

Q&A

解決済

1回答

3602閲覧

Python OpenCV ndarray型のimageのVideoWriterへの書き込み

k_egashi

総合スコア14

OpenCV

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

Python 2.7

Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

0グッド

0クリップ

投稿2018/10/12 02:27

Python OpenCV ndarray型のimageのVideoWriterへの書き込み

カメラから取得した動画をAVIとして保存する機能を作成しております。
産業用カメラのuEyeカメラから流れてきた画像をOpenCVのVideoWriterに保存する事を考えており、以下のサンプルコードを元に作成しております。
https://github.com/dcabecinhas/pyueye

現在、カメラから取得したデータをGUIで表示する部分は動いておりますが、AVIへの書き込みが上手く行えておりません。

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

.writeをする時に上手く保存できていない。
以下に似たようなエラーを報告している方がおり、入力された画像のサイズなどがVideoWriterと違うと保存されない事がわかりました。
https://teratail.com/questions/63352

その後も画像のサイズや型を色々変えてやってみたのですが上手くいきませんでした。

該当のソースコード

元となるコードのmain.pyのprocess_imageの所でAVI化を行っております。

Python

1#!/usr/bin/env python 2# Copyright省略 3 4from pyueye_example_camera import Camera 5from pyueye_example_utils import FrameThread 6from pyueye_example_gui import PyuEyeQtApp, PyuEyeQtView 7from PyQt4 import QtGui 8 9from pyueye import ueye 10 11import cv2 12import numpy as np 13import datetime 14import os 15 16size_width = 1280 17size_height = 1024 18fps = 30.0 19codec = "DIVX" 20aviname = "output.avi" 21avi = cv2.VideoWriter() 22 23def init_avi(): 24 print("init") 25 aviname = datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S.avi") 26 fourcc = cv2.cv.CV_FOURCC(*codec) 27 avi = cv2.VideoWriter(aviname, fourcc, fps, (size_width, size_height)) 28 29def done_avi(): 30 print("done") 31 avi.release() 32 cv2.destroyAllWindows() 33 34def process_image(self, image_data): 35 print("process") 36 # reshape the image data as 1dimensional array 37 image = image_data.as_1d_image() 38 print(type(image_data)) // <type 'instance'> 39 print(type(image)) // <type 'numpy.ndarray'> 40 41 qtgui = QtGui.QImage(image.data, 42 image_data.mem_info.width, 43 image_data.mem_info.height, 44 QtGui.QImage.Format_RGB888) 45 avi.write(cv2.resize(image, (size_width,size_height))) 46 47 # show the image with Qt 48 return qtgui 49 50def main(): 51 # we :wneed a QApplication, that runs our QT Gui Framework 52 app = PyuEyeQtApp() 53 54 init_avi() 55 56 # a basic qt window 57 view = PyuEyeQtView() 58 view.show() 59 view.user_callback = process_image 60 61 # camera class to simplify uEye API access 62 cam = Camera() 63 cam.init() 64 cam.set_colormode(ueye.IS_CM_BGR8_PACKED) 65 cam.set_aoi(0,0, size_width, size_height) 66 cam.alloc() 67 cam.capture_video() 68 69 # a thread that waits for new images and processes all connected views 70 thread = FrameThread(cam, view) 71 thread.start() 72 73 # cleanup 74 print("clean up") 75 app.exit_connect(thread.stop) 76 app.exec_() 77 78 print("thread") 79 thread.stop() 80 thread.join() 81 82 print("cam") 83 cam.stop_video() 84 cam.exit() 85 86 done_avi() 87 88if __name__ == "__main__": 89 main()

補足情報

OS: Ubuntu 16.04.5 LTS
Python: Python 2.7.12
OpenCV: 2.4.9.1
カメラ: USB 3 uEye CP Rev. 2

#####どうぞよろしくお願いいたします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

以下を別のコーデックで試してみてはどうでしょうか。

codec = "DIVX"

image の型は image.dtype で uint8 になっていることを確認してください。


追記

VideoWriter がそもそも使えるのか確認してみてはどうでしょうか

vtest.avi

python

1import cv2 2 3# Video Reader を作成 4cap = cv2.VideoCapture('vtest.avi') 5width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) 6height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) 7fps = cap.get(cv2.CAP_PROP_FPS) 8 9# Video Writer を作成 10fourcc = cv2.VideoWriter_fourcc(*'DIVX') 11writer = cv2.VideoWriter('output.avi', fourcc, fps, (width, height)) 12 13while True: 14 ret, frame = cap.read() 15 if not ret: 16 break 17 writer.write(frame) 18 19writer.release() 20cap.release() 21cv2.destroyAllWindows()

追記

おそらく原因がわかりました。
グローバル変数で avi = cv2.VideoWriter() としたあと、init_avi() 内で avi = cv2.VideoWriter(aviname, fourcc, fps, (size_width, size_height)) としていますが、これはローカル変数のため、関数を抜けた段階で破棄されます。
グローバル変数の avi に代入されているわけではありません。

関数内でグローバル変数に代入する場合は global avi とする必要があります。
こちらの記事 で言語仕様を確認してください。

そのあと、process_image() 内で avi を参照したときは、グローバル変数の avi = cv2.VideoWriter() を参照しています。
そのため、動画は出力されません。
print(avi) でオブジェクトの ID を確認してみてください。

実証コード

python

1import datetime 2 3import cv2 4 5avi = cv2.VideoWriter() 6print(avi) # <VideoWriter 0000016D5B99CAD0> 7 8def init_avi(): 9 aviname = datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S.avi") 10 fourcc = cv2.VideoWriter_fourcc(*"DIVX") 11 avi = cv2.VideoWriter("output.avi", fourcc, 30., (1280, 1024)) 12 print(avi) # <VideoWriter 0000016D5E1BF1B0> 13 14 15def func(): 16 print(avi) # <VideoWriter 0000016D5B99CAD0> 17 18init_avi() 19func()

投稿2018/10/12 03:17

編集2018/10/12 05:22
tiitoi

総合スコア21956

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

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

k_egashi

2018/10/12 04:26

ご回答ありがとうございます。 codecをXVID, MPEG, DIV3, MJPG等色々変更して試してみましたが挙動変わらずでした。 ``` print(image.dtype) ``` ではuint8となっており問題なさそうでした。 それ以外に確認できる項目等あればご教授頂けますか。
tiitoi

2018/10/12 04:33 編集

VideoWriter は使えたことはあるのでしょうか? もし、まだないのであれば、追記したコードで確認してみてください。
k_egashi

2018/10/12 04:52

VideoWriter自体は使えており、追記頂いたコードも問題なく動きました。 よろしくお願いします。
tiitoi

2018/10/12 04:58

五月雨式で申し訳ないですが、image = image_data.as_1d_image() の直後の image.shape はどうなっていますか?
k_egashi

2018/10/12 05:07

こちらこそお手を煩わせてしまい申し訳ございません。 image.shapeの実行結果は以下になりました。 (1024, 1280, 3)
tiitoi

2018/10/12 05:22

おそらく原因がわかったので追記しました。 もし違ったら教えてください。
k_egashi

2018/10/12 05:35

無事動かすことができました!確かにIDが違うものでした。 非常に困っていたので助かりました。本当にありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問