在两个屏幕上预览一个摄像头

时间:2018-04-19 11:25:42

标签: kivy kivy-language

我试图在覆盆子pi上做一个照相机。我使用Kivy框架为我的GUI使用ScreenManager小部件。

我想要一个" CameraOptionScreen"预览设置和其他屏幕" CameraTakeScreen"还有相机预览。

这里是两个屏幕的Kv脚本:

<CameraOptionScreen>:
BoxLayout:
    orientation: 'vertical'
    BoxLayout:
        Label:
            font_size:'40sp'
            text: "test OPTION"
        Camera:
            id: camera
            resolution: 500, 400
            preview_fullscreen: True
    Button:
        text: "OK"
        size_hint: 0.25, 0.1
        pos_hint: {"center_x": 0.5, "center_y": 0.1}
        on_press:
            app.root.transition = SlideTransition(direction='up')
            root.manager.current = 'camera_take'


<CameraTakeScreen>:
    BoxLayout:
        orientation: 'vertical'

        #here the second preview#

        Button:
            text: "OK"
            size_hint: 0.25, 0.1
            pos_hint: {"center_x": 0.5, "center_y": 0.1}

我试图添加一个新的相机小部件而没有想到,我得到了这个错误:

VIDEOIO ERROR: V4L2: Pixel format of incoming image is unsupported by OpenCV
Unable to stop the stream: Device or resource busy
 Traceback (most recent call last):
   File "./multiscreen.py", line 64, in <module>
     sm = Builder.load_file('./multiscreen.kv')
   File "/usr/lib/python2.7/dist-packages/kivy/lang/builder.py", line 301, in load_file
     return self.load_string(data, **kwargs)
   File "/usr/lib/python2.7/dist-packages/kivy/lang/builder.py", line 382, in load_string
     self._apply_rule(widget, parser.root, parser.root)
   File "/usr/lib/python2.7/dist-packages/kivy/lang/builder.py", line 566, in _apply_rule
     self.apply(child)
   File "/usr/lib/python2.7/dist-packages/kivy/lang/builder.py", line 451, in apply
     self._apply_rule(widget, rule, rule, ignored_consts=ignored_consts)
   File "/usr/lib/python2.7/dist-packages/kivy/lang/builder.py", line 612, in _apply_rule
     e), cause=tb)
 kivy.lang.builder.BuilderException: Parser: File "/home/thenewby/Documents/Git/Photomaton_connecte/kivi/multiscreen.kv", line 169:
 ...
     167:        Camera:
     168:            id: camera2
 >>  169:            resolution: 500, 400
     170:            preview_fullscreen: True
     171:            play: True
 ...
 AttributeError: 'NoneType' object has no attribute 'shape'
   File "/usr/lib/python2.7/dist-packages/kivy/lang/builder.py", line 605, in _apply_rule
     setattr(widget_set, key, value)
   File "kivy/weakproxy.pyx", line 33, in kivy.weakproxy.WeakProxy.__setattr__ (kivy/weakproxy.c:1236)
   File "kivy/properties.pyx", line 478, in kivy.properties.Property.__set__ (kivy/properties.c:5171)
   File "kivy/properties.pyx", line 815, in kivy.properties.ListProperty.set (kivy/properties.c:11368)
   File "kivy/properties.pyx", line 516, in kivy.properties.Property.set (kivy/properties.c:5933)
   File "kivy/properties.pyx", line 571, in kivy.properties.Property.dispatch (kivy/properties.c:6614)
   File "kivy/_event.pyx", line 1225, in kivy._event.EventObservers.dispatch (kivy/_event.c:13524)
   File "kivy/_event.pyx", line 1131, in kivy._event.EventObservers._dispatch (kivy/_event.c:12723)
   File "/usr/lib/python2.7/dist-packages/kivy/uix/camera.py", line 103, in _on_index
     resolution=self.resolution, stopped=True)
   File "/usr/lib/python2.7/dist-packages/kivy/core/camera/camera_opencv.py", line 67, in __init__
     super(CameraOpenCV, self).__init__(**kwargs)
   File "/usr/lib/python2.7/dist-packages/kivy/core/camera/__init__.py", line 70, in __init__
     self.init_camera()
   File "/usr/lib/python2.7/dist-packages/kivy/core/camera/camera_opencv.py", line 117, in init_camera
     self._resolution = (int(frame.shape[1]), int(frame.shape[0]))

据我了解,我不能使用资源的两个相机小部件(这是可以理解的)。

考虑到这一点,我需要在我的应用中只有一个相机类实例化。我只看到两个选项:

  • one:在第二个屏幕上重复使用相同的相机小部件。
  • 二:为两个屏幕动态创建和终止相机小部件。

对于第一个解决方案,我在互联网上的不同屏幕上找不到共享或重用小部件的信息。

对于第二个解决方案,我可能会找到一种方法来做到这一点,但我不知道它是否是一个好的和可行的解决方案。

1 个答案:

答案 0 :(得分:0)

我有点找到解决方案。但是有一个小问题。

我在脚本的根目录下创建了一个摄像头小部件,并在显示mu屏幕时设置了其父级。这是python脚本的一部分

cam = Camera(resolution=(320, 240), id="camera")

class CameraOptionScreen(Screen):
    def loadCamera(self):
        self.ids.camBoxOption.add_widget(cam)

    def killCamera(self):
        self.ids.camBoxOption.remove_widget(cam)

class CameraTakeScreen(Screen):
    def loadCamera(self):
        self.ids.camBoxTake.add_widget(cam)
    def killCamera(self):
        self.ids.camBoxTake.remove_widget(cam)

我只是在加载事件时链接了我的方法:

<CameraOptionScreen>:
    on_pre_enter: root.loadCamera()
    on_pre_leave: root.killCamera()
    BoxLayout:
        orientation: 'vertical'
        BoxLayout:
            Label:
                font_size:'40sp'
                text: "test OPTION"
            BoxLayout:
                id: camBoxOption
        Button:
            text: "OK"
            size_hint: 0.25, 0.1
            pos_hint: {"center_x": 0.5, "center_y": 0.1}
            on_press:
                app.root.transition = SlideTransition(direction='up')
                root.manager.current = 'camera_take'

<CameraTakeScreen>:
    on_enter: root.loadCamera()
    on_leave: root.killCamera()
    BoxLayout:
        orientation: 'vertical'
        BoxLayout:
            id: camBoxTake

        Button:
            text: "OK"
            size_hint: 0.25, 0.1
            pos_hint: {"center_x": 0.5, "center_y": 0.1}
            on_press:
                app.root.transition = SlideTransition(direction='up')
                root.manager.current = 'camera_save'

我在工作,但是只有一件事困扰着我。当我在两个屏幕之间进行过渡时,必须在过渡之前删除相机小部件,因此在过渡时不显示相机预览。