Kivy 相机作为 KV 语言小部件

2022-01-15 00:00:00 python opencv kivy kivy-language

问题描述

我正在使用带有网络摄像头的 Kivy.我按照@Arnav 的 this example 使用 opencv 来形成和将相机显示为小部件.我已经扩展"了python中的布局,添加了两个按钮作为测试,为更复杂的布局做准备.

I am using Kivy with a webcam. I have followed this example by @Arnav of using opencv to form and display the camera as a widget. I have "extended" the layout within python it to add two buttons as a test, in preparation for a more complicated layout.

class CamApp(App):
    def build(self):
        self.capture = cv2.VideoCapture(0)
        self.my_camera = KivyCamera(capture=self.capture, fps=30,resolution=(1920,1080))
        root = BoxLayout(orientation = 'vertical')
        root.add_widget(self.my_camera,1)
        box2 = BoxLayout(orientation = 'vertical')
        btn1 = Button(text='Hello world 1')
        btn2 = Button(text='Hello world 2')
        box2.add_widget(btn1)
        box2.add_widget(btn2)
        root.add_widget(box2, 0)
        return root
        #return Builder.load_string(kv)

虽然这可行,但我更愿意将 UI 组件从 python 中移出并放入 kv 语言 文件中.问题是知道如何在 kv 文件中描述"self.my_camera?

While this works I would prefer to move the UI components out of python and into a kv language file. The problem is knowing how to "describe" the self.my_camera in the kv file?

我不确定是否将 KivyCamera 类作为 kv 文件中的 widget 继承,即

I am not sure whether to inherit the KivyCamera class as a widget within the kv file i.e.

kv = '''
<Cam1@KivyCamera>:
    texture: self.my_camera
    resolution: (1920, 1080)
    pos: self.pos
    size: self.size

或者是否使用canvas小部件

<MyWidget>:
    canvas:
        Rectangle:
            source: self.my_camera
            pos: self.pos
            size: self.size

我尝试过其他被黑"的实现,但在所有情况下,问题都是通过 self.my_camera 链接到 kv 文件.

I have tried other "hacked" implementations, but in all cases the problem is linking through the self.my_camera into the kv file.

有什么建议吗?


解决方案

也许这个例子可以帮到你.

Perhaps this example may help you.

# Import 'kivy.core.text' must be called in entry point script
# before import of cv2 to initialize Kivy's text provider.
# This fixes crash on app exit.

import kivy.core.text
import cv2
from kivy.app import App
from kivy.base import EventLoop
from kivy.uix.image import Image
from kivy.clock import Clock
from kivy.graphics.texture import Texture
from kivy.uix.boxlayout import BoxLayout
from kivy.core.window import Window


class KivyCamera(Image):

    def __init__(self, **kwargs):
        super(KivyCamera, self).__init__(**kwargs)
        self.capture = None

    def start(self, capture, fps=30):
        self.capture = capture
        Clock.schedule_interval(self.update, 1.0 / fps)

    def stop(self):
        Clock.unschedule_interval(self.update)
        self.capture = None

    def update(self, dt):
        return_value, frame = self.capture.read()
        if return_value:
            texture = self.texture
            w, h = frame.shape[1], frame.shape[0]
            if not texture or texture.width != w or texture.height != h:
                self.texture = texture = Texture.create(size=(w, h))
                texture.flip_vertical()
            texture.blit_buffer(frame.tobytes(), colorfmt='bgr')
            self.canvas.ask_update()


capture = None


class QrtestHome(BoxLayout):

    def init_qrtest(self):
        pass

    def dostart(self, *largs):
        global capture
        capture = cv2.VideoCapture(0)
        self.ids.qrcam.start(capture)

    def doexit(self):
        global capture
        if capture != None:
            capture.release()
            capture = None
        EventLoop.close()


class qrtestApp(App):

    def build(self):
        Window.clearcolor = (.4,.4,.4,1)
        Window.size = (400, 300)
        homeWin = QrtestHome()
        homeWin.init_qrtest()
        return homeWin

    def on_stop(self):
        global capture
        if capture:
            capture.release()
            capture = None

qrtestApp().run()

还有kv文件:

<QrtestHome>:

    BoxLayout:
        orientation: "vertical"

        Label:
            height: 20
            size_hint_y: None
            text: 'Testing the camera'

        KivyCamera:
            id: qrcam

        BoxLayout:
            orientation: "horizontal"
            height: 20
            size_hint_y: None

            Button:
                id: butt_start
                size_hint: 0.5,1
                text: "start"
                on_press: root.dostart()

            Button:
                id: butt_exit
                text: "quit"
                size_hint: 0.5,1
                on_press: root.doexit()

相关文章