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

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

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

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

Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

Python

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

Q&A

解決済

1回答

1927閲覧

tkinterでカメラアプリを作成した際にエラーが発生する

erisawa

総合スコア12

OpenCV

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

Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

Python

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

0グッド

1クリップ

投稿2020/11/13 02:15

実現したいこと
tkinter画面でカメラのリアルタイムの映像を表示し、スナップショットを実施したい。
エラーはでるものの一応作動しますが、動作がとても遅いです。

import tkinter as tk import cv2 from PIL import Image,ImageTk import numpy as np import tkinter.filedialog as fl import tkinter.messagebox as mb import matplotlib.pyplot as plt import tkinter.ttk as ttk root=tk.Tk() root.title("カメラソフトウェア") root.geometry("800x600") root.resizable(width=False, height=False) #リアルタイム映像を表示するキャンバス作成 canvas1=tk.Canvas(root, width=640, height=480, bg="white") canvas1.place(x=0,y=0) ######################################################################################### #動画を常に表示しておくプログラム def capStart(): try: global c, w, h, img c = cv2.VideoCapture(1) c.set(3,640)#Width:L;1280,2L;1600,A4;2048#プロパティの設定 c.set(4,480)#Height:L;960,2L;1200,A4;1536#プロパティの設定 w, h= c.get(cv2.CAP_PROP_FRAME_WIDTH), c.get(cv2.CAP_PROP_FRAME_HEIGHT)#プロパティの取得 #print('w:'+str(w)+'px+h:'+str(h)+'px') except: import sys print("error-----") print(sys.exec_info()[0]) print(sys.exec_info()[1]) '''終了時の処理はここでは省略します。 c.release() cv2.destroyAllWindows()''' def u():#update global img ret, frame =c.read() if ret: img=ImageTk.PhotoImage(Image.fromarray(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))) canvas1.create_image(w/2,h/2,image=img) else: print("u-Fail") root.after(1,u) capStart() u() ############################################################################################ #スナップショットの関数 def press_snapshot_button(): _, frame=c.read() cv2.imwrite("1021_OK_1.png",frame) ############################################################################################ #スナップショットした画像を別画面に表示する方法 def press_snapshot_Kousin_button(): root2=tk.Tk() root2.title("蒸気流量計読み取りソフトウェア") root2.geometry("640x480") root2.resizable(width=False, height=False) #画像読み込み global img2 img=Image.open("0915.jpg") img2=ImageTk.PhotoImage(img,master=root2) #キャンバス2に画像を表示 canvas=tk.Canvas(root2, width=640, height=480, bg="white") canvas.place(x=0,y=0) canvas.create_image(0,0,image=img2, anchor='nw' ) ########################################################################################### button1 = tk.Button(root, text=u'撮影',height=5,width=15,relief="ridge", command=press_snapshot_button) button1.place(x=40,y=500) button1 = tk.Button(root, text=u'更新',height=5,width=15,relief="ridge", command=press_snapshot_Kousin_button) button1.place(x=150,y=500) root.mainloop()

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

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

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

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

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

guest

回答1

0

ベストアンサー

スナップショット自体は、正常にファイル保存できましたが
どのようなエラーがでますか?


動作が遅い問題の軽減策

一時的な問題回避策)

  • canvas1.delete("all") 画像オブジェクトが蓄積されてるので、毎回クリアする
  • after で呼び出す間隔を10ms 程度に増やす。(負荷軽減)

1ms 毎に更新する必要はなく、
10msの間隔でもフレーム読込の処理を含めて
60fps 程度は確保できると思います。

動作が遅い原因

tkinter のタイマー内で処理する場合、
GUIの描画やマウスなどのイベント操作の合間に処理される為、
タイマーで行う処理が多過ぎると他の処理が滞り、
GUIのレスポンス低下につながります。

解決策

カメラ側の処理にはスレッドを使ってください。

GUI更新は mainloop が動いているスレッドで行う必要があるので、
queue 等を用いて通信します。詳しくはスレッド間通信について調べて下さい。

注意点: 別スレッドからはGUIを直接操作しない事。スレッドセーフではありません。

  • Image.fromarray 迄はサブスレッド側、
  • ImageTk.PhotoImage はメインスレッド側で行うようにします。

スナップショット等、ファイルI/Oが絡む処理も
一時的な遅延になるので、理想的には別スレッドで行った方が良いです。


追記:
もし、読み込んだ画像に対して解析など何か処理を行うのであれば、
マルチプロセスで行う方が適切です。
但し、データの受け渡し・共有方法はプロセス間通信が必要で、
スレッドの場合と異なります。
マルチスレッドでは、GUIの負担軽減である程度の効果は見込めますが、
コア数を活かした最適化にはなりません。


他の問題点

2回目の root2=tk.Tk() について
複数のウインドウを作りたい場合は tk.Toplevel() を使ってください。
Tk() は tkinter を使う際の初期化処理も含む為、
複数回呼び出すのは、他で問題の原因になる事が多いです。


終了時のエラーについては

  • cv2.VideoCapture(1, cv2.CAP_DSHOW)
  • mainloop の後に c.release()

投稿2020/11/13 03:44

編集2020/11/14 01:15
teamikl

総合スコア8760

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問