前提
- Python
- Tkinter
- OpenCV
- webカメラ
###実現したいこと
OpenCVでwebカメラから取得した画像(動画)をウインドウ内に表示したいです。
発生している問題
- 番号リストcv2.imshowならスムーズに画像が切り替わりますが、
別ウインドウを開く必要があります。そうすることなく動画を表示したいです。
0. canvas.itemconfig()
で画像を切り替えようとすると、
画像が消える(一瞬canvasの背景色のみが表示される)→画像が表示される
というプロセスを経るためにスムーズに画像を切り替えることができません。
該当のソースコード
Python
import tkinter as tk import threading as th import cv2 from PIL import Image,ImageTk import numpy as np root=tk.Tk() root.title("camera") root.geometry("720x480") canvas=tk.Canvas(root, width=640, height=480) canvas.pack() def camera(): try: c=cv2.VideoCapture(0) h=c.get(cv2.CAP_PROP_FRAME_HEIGHT) w=c.get(cv2.CAP_PROP_FRAME_WIDTH) i=0 while(True): ret, frame =c.read() if (not ret): break if cv2.waitKey(1)&0xFF==ord('q'): canvas.delete("all") break cv2.imshow('camera', frame) image=ImageTk.PhotoImage(Image.fromarray(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))) if not i:#初回起動時の処理 i=1 canvas.create_image(w/2,h/2,image=image,tag="img") continue canvas.itemconfig("img", image=image) c.release() cv2.destroyAllWindows() except: import sys print(sys.exec_info()[0]) print(sys.exec_info()[1]) t1=th.Thread(target=camera) t1.start() root.mainloop()
試したこと
labelで画像を表示する場合も同じ結果に終わりました。
label.configure(image=image)
###回答をもとにできたもの
aaaa
python
import tkinter as tk import cv2 from PIL import Image,ImageTk import numpy as np root=tk.Tk() root.title("camera") root.geometry("720x480") root.resizable(width=False, height=False) canvas=tk.Canvas(root, width=640, height=480, bg="white") canvas.pack() def capStart(): print('camera-ON') try: global c, w, h, img c=cv2.VideoCapture(0) 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))) canvas.create_image(w/2,h/2,image=img) else: print("u-Fail") root.after(1,u) capStart() u() root.mainloop()
まだ回答がついていません
会員登録して回答してみよう