LoginSignup
4
9

More than 3 years have passed since last update.

PysimpleGUIを用いたOpenCVのカメラ画像表示

Last updated at Posted at 2020-06-14

はじめに

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が押されたらループを抜けるように変更。

4
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
9