python-3.x - Kivy 图像未重新加载且应用程序停止响应
问题描述
我正在尝试使用 Kivy 使用 Python 构建应用程序。这就是我想要实现的目标:
- 使用来自视频或相机的输入来检测图像,使用检测器(为了简化)找到图像中的所有圆圈,并以某种方式突出显示它们,从而产生新的图像。这是由我称之为的类完成的
detector
。Detector 利用 OpenCV 进行图像处理。 - 检测器的输出图像被写入
display.jpg
- Kivy 应用程序的图像字段
source
为display.jpg
- (这不起作用)我使用重新加载图像源,
self.image.reload()
以便我的应用程序为用户刷新输出
这是我的代码
class GUI(App):
def build(self):
self.capture = cv2.VideoCapture(VIDEO_SOURCE)
self.detector = detector(self.capture)
layout = GridLayout(cols=2)
self.InfoStream = Label(text = 'Info', size_hint=(20,80))
StartButton = Button(text = 'Start', size_hint=(80,20))
StartButton.bind(on_press=lambda x:self.start_program())
self.image = Image(source = 'display.jpg')
layout.add_widget(self.image)
layout.add_widget(self.InfoStream)
layout.add_widget(StartButton)
layout.add_widget(Label(text = 'Test'), size_hint=(20,20))
return layout
def start_program(self):
while True:
self.detector.detect_frame()
self.update_image() # After detecting each frame, I run this
def update_image(self, *args):
if self.detector.output_image is not None:
cv2.imwrite('display.jpg', self.detector.output_image)
self.image.reload() # I use reload() to refresh the image on screen
def exit(self):
self.stop()
def on_stop(self):
self.capture.release()
if __name__ == '__main__':
GUI().run()
发生的情况是我可以通过按我的StartButton
. 我在控制台上看到输出,证明它循环运行来自我的视频流的帧,并且我还看到源图像display.jpg
正在实时更新。
但是,在我启动后,应用程序窗口似乎只是冻结了。它“无响应”并变灰,从不显示任何刷新的图像。
根据其他来源的一些现有代码,我还尝试使用计划任务刷新图像Clock.schedule_interval(self.update_image, dt=1)
,但结果是相同的。
我刷新图像的方式正确吗?有更好的方法吗?
解决方案
主线程上的while True
循环将导致您App
无响应。您可以使用Clock.schedule_interval
以下方法消除该循环:
class GUI(App):
def build(self):
self.capture = cv2.VideoCapture(VIDEO_SOURCE)
self.detector = detector(self.capture)
layout = GridLayout(cols=2)
self.InfoStream = Label(text = 'Info', size_hint=(20,80))
StartButton = Button(text = 'Start', size_hint=(80,20))
StartButton.bind(on_press=lambda x:self.start_program())
self.image = Image(source = 'display.jpg')
layout.add_widget(self.image)
layout.add_widget(self.InfoStream)
layout.add_widget(StartButton)
layout.add_widget(Label(text = 'Test'), size_hint=(20,20))
return layout
def start_program(self):
Clock.schedule_interval(self.update_image, 0.05)
def update_image(self, *args):
self.detector.detect_frame()
if self.detector.output_image is not None:
cv2.imwrite('display.jpg', self.detector.output_image)
self.image.reload() # I use reload() to refresh the image on screen
def exit(self):
self.stop()
def on_stop(self):
self.capture.release()
if __name__ == '__main__':
GUI().run()
这是另一个问题,海报使用 aTexture
而不是将捕获的图像写入文件。可能是更有效的方法。
推荐阅读
- javascript - 在 express 服务器上提供 create-react-app 构建文件
- javascript - 从本地存储中删除仅选定的列表项 - 纯 JS
- django - 想要显示详细视图,单击列表视图中的链接
- vb.net - 在 windows 中生成声音频率 - VB.Net
- sql - 如何插入具有 ADT 类型属性的数据库表中?使用 Oracle Live SQL
- python - 你如何在python中更改变量函数参数
- assembly - 优化线性序列之和 = n * (n+1)/2 - 比 lea / imul / shrd 快吗?
- r - 为什么从参数列表中通过迭代创建pdf会因for/lapply而失败?
- flutter - 使用颤振向 ClipRRect 添加阴影和彩色边框的最佳方法
- javascript - Redux 只调度了一半的函数