Kivy 图像不会重新加载并且应用程序停止响应
Kivy image does not reload and app stops responding
我正在尝试使用 Kivy Python 构建一个应用程序。这就是我想要实现的目标:
- 使用来自视频或相机的输入来检测图像,使用检测器(为了简化)找到图像中的所有圆圈,并以某种方式突出显示它们,从而生成新图像。这是由 class 完成的,我称之为
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
正在实时更新。
但是,在我启动后,应用程序 window 似乎只是死机了。它 "Not responding" 变灰,从不显示任何刷新的图像。
根据其他来源的一些现有代码,我也尝试使用计划任务刷新图像,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()
这是 another 发帖人使用 Texture
而不是将捕获的图像写入文件的问题。可能是一种更有效的方法。
我正在尝试使用 Kivy Python 构建一个应用程序。这就是我想要实现的目标:
- 使用来自视频或相机的输入来检测图像,使用检测器(为了简化)找到图像中的所有圆圈,并以某种方式突出显示它们,从而生成新图像。这是由 class 完成的,我称之为
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
正在实时更新。
但是,在我启动后,应用程序 window 似乎只是死机了。它 "Not responding" 变灰,从不显示任何刷新的图像。
根据其他来源的一些现有代码,我也尝试使用计划任务刷新图像,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()
这是 another 发帖人使用 Texture
而不是将捕获的图像写入文件的问题。可能是一种更有效的方法。