Kivy образ не перезагружается и приложение перестает отвечать - PullRequest
0 голосов
/ 18 декабря 2018

Я пытаюсь создать приложение на Python, используя Kivy.Вот чего я пытаюсь достичь:

  1. Используйте входные данные с видео или камеры для обнаружения изображений с помощью детектора, который (для упрощения) находит все круги на изображении и как-то выделяет их, производяновое изображение в результате.Это делается классом, который я называю detector.Детектор использует OpenCV для обработки изображений.
  2. Выходное изображение детектора записывается в display.jpg
  3. Приложение Kivy имеет поле изображения, для которого source равно display.jpg
  4. ( Это не работает ) Я перезагружаю источник изображения, используя 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), но в результатебыло то же самое.

Правильный ли мой способ обновления изображения?Есть ли лучшие способы сделать это?

1 Ответ

0 голосов
/ 19 декабря 2018

Цикл 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()

Вот еще один вопрос, где постер использует Texture вместо записи захваченного изображения в файл,Может быть, более эффективный подход.

...