【问题标题】:Why can I not use different camera sources within Opencv and Kivy?为什么我不能在 Opencv 和 Kivy 中使用不同的相机源?
【发布时间】:2020-07-14 19:51:37
【问题描述】:

我试图理解为什么我不能在 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()

我也知道这段代码没有得到应有的优化。在开始实现更多之前,我正在编写基本的运行代码。我希望我可以在主屏幕上安装 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://':

我该如何解决这个问题?

【问题讨论】:

  • 看起来您的具体问题可能与覆盖 source 的正常含义有关,因为 kivy 图像小部件已经具有此功能。尝试使用其他名称。
  • 您的解决方案有效。谢谢!
  • 用新代码和错误替换你的例子,然后
  • 我一定是在某处错过了对 source 的使用。我将发布工作代码。谢谢!

标签: python opencv kivy kivy-language


【解决方案1】:

感谢 cmets 中的恶劣情况,代码现在可以正常工作,他还要求我重新发布工作代码。这里:

# 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()

【讨论】:

    猜你喜欢
    • 2013-03-09
    • 1970-01-01
    • 2021-11-10
    • 1970-01-01
    • 2019-09-07
    • 1970-01-01
    • 2016-05-02
    • 1970-01-01
    • 2021-02-28
    相关资源
    最近更新 更多