class Camera(): def init(self, top): self.top = top self.h = int(data_demo.window_height // 1.5) self.w = int(data_demo.window_width // 1.74) self.canvas2 = Canvas(self.top, bg='LightSkyBlue', width=self.w, height=self.h, highlightthickness=2, highlightbackground='Black') self.canvas2.place(relx=0.0, rely=0.032) self.label = tk.Label(self.canvas2, text='摄像头显示区!', font=("黑体", 25), width=15, height=1) self.label.place(relx=0.32, rely=0.50, anchor='nw') self.queue = Queue() # 创建一个队列 def Firing_run(self, button_id): self.bool = True self.label.destroy() self.cap = cv2.VideoCapture(0) t = threading.Thread(target=self.windows_display) t.start() button_id.config(text='关闭摄像头', command=lambda: self.Cease_stop(button_id)) def Cease_stop(self, button_id): self.bool = False button_id.config(text='打开摄像头', command=lambda: self.Firing_run(button_id)) def windows_display(self): if self.bool: ref, frame = self.cap.read() if ref: image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) image1 = Image.fromarray(image) image2 = image1.resize((self.w, self.h), Image.ANTIALIAS) photo = ImageTk.PhotoImage(image=image2) self.canvas2.create_image(0, 0, image=photo, anchor=tk.NW) self.canvas2.update() self.canvas2.after(15, self.windows_display())怎么优化
时间: 2024-03-29 20:36:23 浏览: 119
可以考虑以下几种优化方法:
1. 优化图像处理速度:可以采用一些优化的图像处理算法或者使用C++等高性能语言编写图像处理的部分,提高图像处理速度。
2. 减少线程间的通信:使用队列可以避免多个线程直接进行通信,但是每次从队列中读取数据也会有一定的开销,可以考虑使用共享内存等更高效的通信方式。
3. 优化界面显示:界面显示的部分可以使用异步更新的方式,避免界面卡顿或者闪烁的问题。
4. 合理利用硬件资源:可以考虑使用GPU等硬件加速技术来加快图像处理的速度,同时也可以考虑使用多个摄像头或者多个线程来进行并行处理。
相关问题
class Camera(): def __init__(self, top): self.top = top self.h = int(data_demo.window_height // 1.5) self.w = int(data_demo.window_width // 1.74) self.canvas2 = Canvas(self.top, bg='LightSkyBlue', width=self.w, height=self.h, highlightthickness=2, highlightbackground='Black') self.canvas2.place(relx=0.0, rely=0.032) label = tk.Label(self.canvas2, text='摄像头显示区!', font=("黑体", 25), width=15, height=1) label.place(relx=0.32, rely=0.47, anchor='nw') def Thread_(self): self.bool = True self.cap = cv2.VideoCapture(0) t = threading.Thread(target=self.windows_display()) t.start() def windows_display(self): self.canvas2.delete('all') while self.bool: if data_demo.display_id is True: ref, frame = self.cap.read() image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) image1 = Image.fromarray(image) image2 = image1.resize((self.w, self.h), Image.ANTIALIAS) self.photo = ImageTk.PhotoImage(image=image2) self.canvas2.create_image(0, 0, image=self.photo, anchor=tk.NW) self.canvas2.update() self.canvas2.after(15, self.windows_display())这个为什么会报错
这段代码中,`threading.Thread()` 方法的 `target` 参数应该传递一个函数名,而不是一个函数的返回值,因此需要将 `self.windows_display()` 修改为 `self.windows_display`。
此外,在 `windows_display()` 方法的最后,应该调用 `after()` 方法来实现定时更新画面,而不是在方法内部递归调用自身。递归调用会导致栈溢出,程序崩溃。
修改后的代码如下:
```python
class Camera():
def __init__(self, top):
self.top = top
self.h = int(data_demo.window_height // 1.5)
self.w = int(data_demo.window_width // 1.74)
self.canvas2 = Canvas(self.top, bg='LightSkyBlue', width=self.w, height=self.h,
highlightthickness=2, highlightbackground='Black')
self.canvas2.place(relx=0.0, rely=0.032)
label = tk.Label(self.canvas2, text='摄像头显示区!', font=("黑体", 25), width=15, height=1)
label.place(relx=0.32, rely=0.47, anchor='nw')
def Thread_(self):
self.bool = True
self.cap = cv2.VideoCapture(0)
t = threading.Thread(target=self.windows_display)
t.start()
def windows_display(self):
self.canvas2.delete('all')
while self.bool:
if data_demo.display_id is True:
ref, frame = self.cap.read()
image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
image1 = Image.fromarray(image)
image2 = image1.resize((self.w, self.h), Image.ANTIALIAS)
self.photo = ImageTk.PhotoImage(image=image2)
self.canvas2.create_image(0, 0, image=self.photo, anchor=tk.NW)
self.canvas2.update()
self.canvas2.after(15)
```
import threading import cv2 import tkinter as tk from tkinter import * from PIL import Image, ImageTk#图像控件 from Background.Thread_Demo import Thread_data from Data_demo import data_demo class Camera(): def __init__(self, top): self.top = top self.h = int(data_demo.window_height // 1.5) self.w = int(data_demo.window_width // 1.74) self.canvas2 = Canvas(self.top, bg='LightSkyBlue', width=self.w, height=self.h, highlightthickness=2, highlightbackground='Black') self.canvas2.place(relx=0.0, rely=0.032) self.label = tk.Label(self.canvas2, text='摄像头显示区!', font=("黑体", 25), width=15, height=1) self.label.place(relx=0.32, rely=0.50, anchor='nw') def Firing_run(self, button_id): self.bool = True self.label.destroy() self.cap = cv2.VideoCapture(0) t = threading.Thread(target=self.windows_display) t.start() button_id.config(text='关闭摄像头', command=lambda: self.Cease_stop(button_id)) def Cease_stop(self, button_id): self.bool = False button_id.config(text='打开摄像头', command=lambda: self.Firing_run(button_id)) def windows_display(self): while self.bool: ref, frame = self.cap.read() cv2.waitKey(1) if ref: image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) image1 = Image.fromarray(image) image2 = image1.resize((self.w, self.h), Image.ANTIALIAS) self.photo = ImageTk.PhotoImage(image=image2) self.canvas2.create_image(0, 0, image=self.photo, anchor=tk.NW) # self.canvas2.update() self.canvas2.after(15)中t = threading.Thread(target=self.windows_display)调用摄像头会闪烁,但是t = threading.Thread(target=self.windows_display())却不会
原因是当您使用`t = threading.Thread(target=self.windows_display)`时,它会将`self.windows_display()`作为一个参数,而不是一个可调用的函数。因此,线程将立即运行`self.windows_display()`函数,并将其返回值(None)传递给`t`。这意味着您的线程实际上不会运行`self.windows_display()`函数,而是只运行了一次,并立即停止。
相反,当您使用`t = threading.Thread(target=self.windows_display)`时,它会将`self.windows_display`作为一个可调用的函数传递给`t`,因此线程将运行`self.windows_display`函数,并在后台持续运行。
因此,您应该修改线程创建代码如下:
```
t = threading.Thread(target=self.windows_display)
```
而不是:
```
t = threading.Thread(target=self.windows_display())
```
阅读全文