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

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

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

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

Python 3.x

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

Qt

QtはGUIプログラムの開発で広く使われているクロスプラットフォーム開発のフレームワークです。

Q&A

解決済

1回答

2100閲覧

PyCapture2でThreadを使っているのにTimer関連のエラーが出る

dinosauria123

総合スコア25

OpenCV

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

Python 3.x

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

Qt

QtはGUIプログラムの開発で広く使われているクロスプラットフォーム開発のフレームワークです。

0グッド

0クリップ

投稿2018/10/29 02:35

編集2018/10/29 07:55

前提・実現したいこと

Python3.5+PyCapture2+PyQt5でビデオキャプチャするプログラムを作っています。

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

画像はキャプチャできるが、以下のエラーが出続ける。 QObject::killTimer: Timers cannot be stopped from another thread QBasicTimer::stop: Failed. Possibly trying to stop from a different thread

該当のソースコード

Python3.5

1 2# -*- coding: utf-8 -*- 3from PyQt5 import QtCore, QtGui, QtWidgets 4from PyQt5.QtCore import QThread 5import cv2 6import PyCapture2 7import numpy as np 8 9class Ui_MainWindow(object): 10 11 def __init__(self, parent=None): 12 13 MainWindow.setObjectName("MainWindow") 14 MainWindow.resize(600, 400) 15 self.centralwidget = QtWidgets.QWidget(MainWindow) 16 self.centralwidget.setObjectName("centralwidget") 17 18 self.graphicsView = QtWidgets.QGraphicsView(self.centralwidget) 19 self.graphicsView.setGeometry(QtCore.QRect(150, 20, 400, 300)) 20 self.graphicsView.setObjectName("graphicsView") 21 22 MainWindow.setCentralWidget(self.centralwidget) 23 24 self.Thread = CapThread() 25 self.Thread.start() 26 27class CapThread(QThread): 28 29 def __init__(self): 30 QThread.__init__(self) 31 32 def run(QMainWindow): 33 bus = PyCapture2.BusManager() 34 uid = bus.getCameraFromIndex(0) 35 36 c = PyCapture2.Camera() 37 c.connect(uid) 38 39 while True: 40 41 c.startCapture() 42 img = c.retrieveBuffer() 43 c.stopCapture() 44 45 cv_img1 = np.array(img.getData(), dtype="uint8").reshape((img.getRows(), img.getCols())); 46 cv_img = cv2.cvtColor(cv_img1, cv2.COLOR_BAYER_BG2BGR) 47 cv_img = cv2.resize(cv_img,(380,270)) 48 49 height, width, dim = cv_img.shape 50 bytesPerLine = dim * width 51 image = QtGui.QImage(cv_img.data, width, height, bytesPerLine, QtGui.QImage.Format_RGB888) 52 item = QtWidgets.QGraphicsPixmapItem(QtGui.QPixmap.fromImage(image)) 53 scene = QtWidgets.QGraphicsScene() 54 scene.addItem(item) 55 ui.graphicsView.setScene(scene) 56 57 58if __name__ == "__main__": 59 import sys 60 app = QtWidgets.QApplication(sys.argv) 61 MainWindow = QtWidgets.QMainWindow() 62 ui = Ui_MainWindow() 63 MainWindow.show() 64 sys.exit(app.exec_()) 65

試したこと

Threadを使わずにWhileだけで回すと画像が出ない。

補足情報(FW/ツールのバージョンなど)

ホスト:Windows10、FLIRのカメラ使用

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

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

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

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

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

guest

回答1

0

ベストアンサー

全体像がコードで示されていませんが一般的な話として、以下の注意が必要です。

・UIコントローラの操作はUIスレッドで行うことが大前提
・キャプチャなどスレッドで行う場合、データを格納するだけにする、あるいは共有メモリなどUIスレッドで参照できる領域にコピーするだけ
・UIスレッド側ではタイマーなどを利用して、参照する領域からデータを読みだして、描画するようにする

投稿2018/10/29 06:26

t_obara

総合スコア5488

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

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

dinosauria123

2018/10/29 07:31

ありがとうございます。取り急ぎ動くコード(カメラはつながないといけませんが)をアップしました。 より詳細に教えていただけるとありがたいです。
t_obara

2018/10/29 08:10

スレッドの中で、Widgetへのアクセスはしないようにする、UIスレッドでタイマーを起動して、キャプチャしたデータを参照、スレッドで行なっているWidgetへのアクセスをタイマーの中で行うようにする
dinosauria123

2018/10/29 23:43

ありがとうございます。Timerを使って、エラーが出なくなりました。 # -*- coding: utf-8 -*- from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5.QtWidgets import (QMessageBox) import cv2 import PyCapture2 import numpy as np class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.resize(700, 400) self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") self.graphicsView = QtWidgets.QGraphicsView(self.centralwidget) self.graphicsView.setGeometry(QtCore.QRect(150, 20, 500, 300)) self.graphicsView.setObjectName("graphicsView") MainWindow.setCentralWidget(self.centralwidget) #update timer timer = QtCore.QTimer(self.graphicsView) timer.timeout.connect(self.set) timer.start() def set(self): bus = PyCapture2.BusManager() uid = bus.getCameraFromIndex(0) c = PyCapture2.Camera() c.connect(uid) c.startCapture() img = c.retrieveBuffer() c.stopCapture() cv_img1 = np.array(img.getData(), dtype="uint8").reshape((img.getRows(), img.getCols())); cv_img = cv2.cvtColor(cv_img1, cv2.COLOR_BAYER_BG2BGR) cv_img = cv2.resize(cv_img,(480,270)) height, width, dim = cv_img.shape bytesPerLine = dim * width self.image = QtGui.QImage(cv_img.data, width, height, bytesPerLine, QtGui.QImage.Format_RGB888) self.item = QtWidgets.QGraphicsPixmapItem(QtGui.QPixmap.fromImage(self.image)) self.scene = QtWidgets.QGraphicsScene() self.scene.addItem(self.item) self.graphicsView.setScene(self.scene) if __name__ == "__main__": import sys app = QtWidgets.QApplication(sys.argv) MainWindow = QtWidgets.QMainWindow() ui = Ui_MainWindow() ui.setupUi(MainWindow) MainWindow.show() sys.exit(app.exec_())
t_obara

2018/10/30 03:52

タイマーだけでキャプチャの間隔を制御しようとすると、正確なフレームレート制御はできませんが、用途によってはそれもアリかと。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問