####はじめに
PysimpleGUIのデモコードをそのままコピーペーストしても動かなかったので、修正したコードを覚えとして載せておきます。
####参考 PysimpleGUIのデモコード
Demo program that displays a webcam using OpenCV
####動作環境
Windows10 64bit
Anaconda
python 3.7
OpenCV 4.2.0 (conda-forge からインストール)
####修正したコード
import PySimpleGUI as sg
import cv2
import numpy as np
"""
Demo program that displays a webcam using OpenCV
"""
def main():
sg.theme('Black')
# define the window layout
layout = [
[sg.Text('Realtime movie', size=(40, 1), justification='center', font='Helvetica 20',key='-status-')],
[sg.Image(filename='', key='image')],
[sg.Button('Record', size=(10, 1), font='Helvetica 14'),
sg.Button('Stop', size=(10, 1), font='Helvetica 14'),
sg.Button('Exit', size=(10, 1), font='Helvetica 14'), ]
]
# create the window and show it without the plot
window = sg.Window('Realtime movie',
layout, location=(800, 400))
# ---===--- Event LOOP Read and display frames, operate the GUI --- #
recording = False
while True:
event, values = window.read(timeout=20)
if event in (None, 'Exit'):
break
elif event == 'Record':
window['-status-'].update("Record")
cap = cv2.VideoCapture(0,cv2.CAP_DSHOW) #1
# cap = cv2.VideoCapture(0)
recording = True
elif event == 'Stop':
window['-status-'].update("Stop")
recording = False
img = np.full((480, 640), 0)
# this is faster, shorter and needs less includes
imgbytes = cv2.imencode('.png', img)[1].tobytes()
window['image'].update(data=imgbytes)
cap.release() #2
cv2.destroyAllWindows()
if recording:
ret, frame = cap.read()
if ret is True:
imgbytes = cv2.imencode('.png', frame)[1].tobytes()
window['image'].update(data=imgbytes)
window.close()
if __name__ == '__main__':
main()
####修正点#1
cap = cv2.VideoCapture(0,cv2.CAP_DSHOW) #1
[ WARN:1] global ..\modules\videoio\src\cap_msmf.cpp (674) SourceReaderCB::~SourceReaderCB terminating async callback
Direct Showの設定をするとterminating async callbackのエラーは出なくなりますが、設定スピード(フレームレート)が遅くなることがあるようです。(私もフレームレートを測ってみたら30fpsから5fpsに落ちました。)
参考:
WARN:0 terminating async callback error in cv2
【openCV】遅いのはCAP_DSHOWだった?【Webカメラ】
####修正点#2
不要かもしれませんが、
cap.release()
cv2.destroyAllWindows() #2
を入れてリリースしています。
####その他の修正点
・'Record'が押されたらVideoCaptureが呼ばれるように変更。
・NoneとExitが押されたらループを抜けるように変更。