Почему я не могу использовать разные источники камеры в Opencv и Kivy? - PullRequest
0 голосов
/ 14 июля 2020

Я пытаюсь понять, почему я не могу использовать разные источники в качестве устройства захвата видео в Opencv и Kivy. В настоящее время я пытаюсь (и не могу) реализовать язык kv для размещения виджета камеры. Вот что у меня есть сейчас:

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.gridlayout import GridLayout
from kivy.uix.image import Image
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.clock import Clock
from kivy.graphics.texture import Texture
from kivy.lang import Builder
from kivy.uix.tabbedpanel import TabbedPanel
from kivy.properties import ObjectProperty, NumericProperty


# 1.2 other libraries needed that are not a part of kivy
import cv2
import numpy as np
import pygame
from pygame.locals import *
import serial

# 2. Variables (declared after structural code is done)

# 3. tabpanelkv kv file
Builder.load_string("""

<tabpanelkv>:
    size_hint: 1, 1
    pos_hint: {'center_x': .5, 'center_y': .5}
    do_default_tab: False

    TabbedPanelItem:
        text: 'Cameras'
        GridLayout:
            rows: 2
            cols: 1
            GridLayout:
                size_hint: 1, 1.5
                rows: 1
                cols: 1
                KivyCamera:
                    source: 
            GridLayout:
                rows: 1
                cols: 2
                Button:
                    text: 'Cam2'
                Button:
                    text: 'Cam3'

    TabbedPanelItem:
        text: 'Diagnostics'
        GridLayout:
            rows: 4
            cols: 10
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
""")

class KivyCamera(Image):
    source = ObjectProperty()
    fps = NumericProperty(30)

    def __init__(self, **kwargs):
        super(KivyCamera, self).__init__(**kwargs)
        self._capture = None
        if self.source is not None:
            self._capture = cv2.VideoCapture(self.source)
        Clock.schedule_interval(self.update, 1.0 / self.fps)

    def on_source(self, *args):
        if self._capture is not None:
            self._capture.release()
        self._capture = cv2.VideoCapture(self.source)

    @property
    def capture(self):
        return self._capture

    def update(self, dt):
        ret, frame = self.capture.read()
        if ret:
            buf1 = cv2.flip(frame, 0)
            buf = buf1.tostring()
            image_texture = Texture.create(
                size=(frame.shape[1], frame.shape[0]), colorfmt="bgr"
            )
            image_texture.blit_buffer(buf, colorfmt="bgr", bufferfmt="ubyte")
            self.texture = image_texture

# 5. tabpanelkv class
class tabpanelkv(TabbedPanel):
    pass

# 6. Main Class
class MainClass(App, GridLayout):
    def build(self):
        return tabpanelkv()

# 7. Main Loop
if __name__ == '__main__':
    MainClass().run()

Также я понимаю, что этот код не так оптимизирован, как должен быть. Я работаю над основным исполняемым кодом c, прежде чем приступить к реализации других. Я надеюсь, что у меня будет 3 внешних USB-камеры на главном экране и куча других виджетов на другой вкладке. Но по какой-то причине код выводится как ошибка:

 kivy.lang.builder.BuilderException: Parser: File "<inline>", line 18:
 ...
      16:                cols: 1
      17:                KivyCamera:
 >>   18:                    source: 2
      19:            GridLayout:
      20:                rows: 1
 ...
 TypeError: 'int' object is not subscriptable
   File "/home/mlees/kivy_venv/lib/python3.6/site-packages/kivy/lang/builder.py", line 700, in _apply_rule
     setattr(widget_set, key, value)
   File "kivy/weakproxy.pyx", line 35, in kivy.weakproxy.WeakProxy.__setattr__
   File "kivy/properties.pyx", line 497, in kivy.properties.Property.__set__
   File "kivy/properties.pyx", line 544, in kivy.properties.Property.set
   File "kivy/properties.pyx", line 599, in kivy.properties.Property.dispatch
   File "kivy/_event.pyx", line 1214, in kivy._event.EventObservers.dispatch
   File "kivy/_event.pyx", line 1120, in kivy._event.EventObservers._dispatch
   File "/home/mlees/kivy_venv/lib/python3.6/site-packages/kivy/uix/image.py", line 257, in texture_update
     filename = resource_find(self.source)
   File "/home/mlees/kivy_venv/lib/python3.6/site-packages/kivy/resources.py", line 52, in resource_find
     if filename[:8] == 'atlas://':

Как я могу это исправить?

1 Ответ

0 голосов
/ 14 июля 2020

Благодаря резкости в комментариях, код теперь работает, и он также попросил меня повторно опубликовать рабочий код. Здесь:

# 1. Import necessary libraries
# 1.1 Kivy libraries and imports
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.gridlayout import GridLayout
from kivy.uix.image import Image
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.clock import Clock
from kivy.graphics.texture import Texture
from kivy.lang import Builder
from kivy.uix.tabbedpanel import TabbedPanel
from kivy.properties import ObjectProperty, NumericProperty


# 1.2 other libraries needed that are not a part of kivy
import cv2
import numpy as np
import pygame
from pygame.locals import *
import serial

# 2. Variables (declared after structural code is done)

# 3. tabpanelkv kv file
Builder.load_string("""

<tabpanelkv>:
    size_hint: 1, 1
    pos_hint: {'center_x': .5, 'center_y': .5}
    do_default_tab: False

    TabbedPanelItem:
        text: 'Cameras'
        GridLayout:
            rows: 2
            cols: 1
            GridLayout:
                size_hint: 1, 1.5
                rows: 1
                cols: 1
                KivyCamera:
                    cam: 2
            GridLayout:
                rows: 1
                cols: 2
                Button:
                    text: 'Cam2'
                Button:
                    text: 'Cam3'

    TabbedPanelItem:
        text: 'Diagnostics'
        GridLayout:
            rows: 4
            cols: 10
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
            Button:
                text: 'Button'
""")

class KivyCamera(Image):
    cam = ObjectProperty()
    fps = NumericProperty(30)

    def __init__(self, **kwargs):
        super(KivyCamera, self).__init__(**kwargs)
        self._capture = None
        if self.cam is not None:
            self._capture = cv2.VideoCapture(self.cam)
        Clock.schedule_interval(self.update, 1.0 / self.fps)

    def on_cam(self, *args):
        if self._capture is not None:
            self._capture.release()
        self._capture = cv2.VideoCapture(self.cam)

    @property
    def capture(self):
        return self._capture

    def update(self, dt):
        ret, frame = self.capture.read()
        if ret:
            buf1 = cv2.flip(frame, 0)
            buf = buf1.tostring()
            image_texture = Texture.create(
                size=(frame.shape[1], frame.shape[0]), colorfmt="bgr"
            )
            image_texture.blit_buffer(buf, colorfmt="bgr", bufferfmt="ubyte")
            self.texture = image_texture

# 5. tabpanelkv class
class tabpanelkv(TabbedPanel):
    pass

# 6. Main Class
class MainClass(App, GridLayout):
    def build(self):
        return tabpanelkv()

# 7. Main Loop
if __name__ == '__main__':
    MainClass().run()
...