Python 3.x Kivy图像不重新加载,应用程序停止响应

Python 3.x Kivy图像不重新加载,应用程序停止响应,python-3.x,kivy,opencv3.0,Python 3.x,Kivy,Opencv3.0,我正在尝试使用Kivy用Python构建一个应用程序。这就是我努力实现的目标: 使用来自视频或相机的输入来检测图像,使用检测器来简化查找图像中的所有圆,并以某种方式高亮显示它们,从而生成新图像。这是由一个我称之为detector的类完成的。探测器利用OpenCV进行图像处理。 探测器的输出图像被写入display.jpg Kivy应用程序有一个源为display.jpg的图像字段 这不起作用。我使用self.image.reload重新加载图像源,以便我的应用程序为用户刷新输出 这是我的密码 c

我正在尝试使用Kivy用Python构建一个应用程序。这就是我努力实现的目标:

使用来自视频或相机的输入来检测图像,使用检测器来简化查找图像中的所有圆,并以某种方式高亮显示它们,从而生成新图像。这是由一个我称之为detector的类完成的。探测器利用OpenCV进行图像处理。 探测器的输出图像被写入display.jpg Kivy应用程序有一个源为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成功启动应用程序。我看到控制台上的输出证明它在我的视频流的帧中循环运行,我还看到源image display.jpg正在实时更新

然而,在我启动之后,应用程序窗口似乎完全冻结了。它没有响应并变灰,从不显示任何刷新的图像

根据其他来源的一些现有代码,我还尝试使用计划任务刷新映像,使用Clock.schedule\u intervalself.update\u image,dt=1,但结果相同

我刷新图像的方式正确吗?有更好的方法吗?

主线程上的while True循环将导致应用程序无响应。您可以使用Clock.schedule\u 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()

这里有一个问题,海报在哪里使用纹理而不是将捕获的图像写入文件。可能是一种更有效的方法。

如果在主线程上运行while True循环,则应用程序将始终没有响应。您可以再次尝试Clock.schedule\u interval方法,但使用它替换整个while True循环。@JohnAnderson谢谢!成功了!我不喜欢它强迫我把我的电话和探测器同步,但你确实发现了我的问题。如果你想详细说明答案,我很乐意接受。