我有两个课程,并使用tkinter演示。
class App:
def __init__(self, window, window_title, video_source=0):
self.window = window
self.window.title(window_title)
self.video_source = video_source
# open video source (by default this will try to open the computer webcam)
self.vid = MyVideoCapture(self.video_source)
# Create a canvas that can fit the above video source size
self.canvas = tkinter.Canvas(window).place(x=50, y=0)
# set plot parameter
self.fig = Figure(figsize=(7, 4), dpi=100)
self.fresh = FigureCanvasTkAgg(self.fig, master=self.window)
self.ax1 = self.fig.add_subplot(211)
self.ax2 = self.fig.add_subplot(212)
self.fresh.get_tk_widget().place(x=700, y=0)
self.window.geometry('1500x550')
# Camera thread
self.photo = None
self.delay = 15
self.t = threading.Thread(target=self.update, args=())
self.t.setDaemon(True)
self.t.start()
def refresh(self, data):
sample_track = pd.read_csv('/home/share/sample_track.csv')
x = [i for i in range(len(sample_track))]
y = sample_track['0']
xdata = [i for i in range(len(data))]
ydata = data
self.ax1.plot(x, y, 'bo--')
self.ax2.plot(xdata, ydata, 'ro--')
self.fresh.draw()
def update(self):
# Get a frame from the video source
ret, frame = self.vid.get_frame()
if ret:
self.photo = PIL.ImageTk.PhotoImage(image=PIL.Image.fromarray(frame))
self.canvas.create_image(0, 0, image=self.photo, anchor=tkinter.NW)
self.window.after(self.delay, self.update)
class MyVideoCapture:
def __init__(self, video_source=0):
# Open the video source
self.vid = cv2.VideoCapture(video_source)
if not self.vid.isOpened():
raise ValueError("Unable to open video source", video_source)
self.ret = None
def get_frame(self):
if self.vid.isOpened():
self.ret, frame = self.vid.read()
if self.ret:
# Return a boolean success flag and the current frame converted to BGR
return self.ret, cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
else:
return self.ret, None
if __name__ == '__main__':
win = tkinter.Tk()
panel = App(win, "Dance")
value = []
for i in range(15):
value.append(np.random.randint(0, 800))
panel.refresh(data=value)
time.sleep(0.1)
win.mainloop()
我想启动网络摄像头并同时刷新图形。 我尝试使用线程,但仍然失败。 发生以下错误:
我该如何解决?
答案 0 :(得分:1)
这是一台正在工作的tkinter
相机,是直接从here拍摄的(通过快速搜索“ tkinter相机”找到):
import tkinter
import cv2
import PIL.Image, PIL.ImageTk
import time
class App:
def __init__(self, window, window_title, video_source=0):
self.window = window
self.window.title(window_title)
self.video_source = video_source
# open video source (by default this will try to open the computer webcam)
self.vid = MyVideoCapture(self.video_source)
# Create a canvas that can fit the above video source size
self.canvas = tkinter.Canvas(window, width = self.vid.width, height = self.vid.height)
self.canvas.pack()
# Button that lets the user take a snapshot
self.btn_snapshot=tkinter.Button(window, text="Snapshot", width=50, command=self.snapshot)
self.btn_snapshot.pack(anchor=tkinter.CENTER, expand=True)
# After it is called once, the update method will be automatically called every delay milliseconds
self.delay = 15
self.update()
self.window.mainloop()
def snapshot(self):
# Get a frame from the video source
ret, frame = self.vid.get_frame()
if ret:
cv2.imwrite("frame-" + time.strftime("%d-%m-%Y-%H-%M-%S") + ".jpg", cv2.cvtColor(frame, cv2.COLOR_RGB2BGR))
def update(self):
# Get a frame from the video source
ret, frame = self.vid.get_frame()
if ret:
self.photo = PIL.ImageTk.PhotoImage(image = PIL.Image.fromarray(frame))
self.canvas.create_image(0, 0, image = self.photo, anchor = tkinter.NW)
self.window.after(self.delay, self.update)
class MyVideoCapture:
def __init__(self, video_source=0):
# Open the video source
self.vid = cv2.VideoCapture(video_source)
if not self.vid.isOpened():
raise ValueError("Unable to open video source", video_source)
# Get video source width and height
self.width = self.vid.get(cv2.CAP_PROP_FRAME_WIDTH)
self.height = self.vid.get(cv2.CAP_PROP_FRAME_HEIGHT)
def get_frame(self):
if self.vid.isOpened():
ret, frame = self.vid.read()
if ret:
# Return a boolean success flag and the current frame converted to BGR
return (ret, cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
else:
return (ret, None)
else:
return (ret, None)
# Release the video source when the object is destroyed
def __del__(self):
if self.vid.isOpened():
self.vid.release()
# Create a window and pass it to the Application object
App(tkinter.Tk(), "Tkinter and OpenCV")