创建 OpenCV 视频小部件以在 Kivy 中使用
Create OpenCV Video Widgets to use in Kivy
我有 2 到 4 个 rtsp 流,我想在 Kivy 的框布局中显示,但我似乎无法弄清楚如何使用 kv 语言来实现这一点。我可以使用此代码显示一个摄像头:
class KivyCamera(Image):
def __init__(self, capture, fps, **kwargs):
super(KivyCamera, self).__init__(**kwargs)
self.capture = capture
Clock.schedule_interval(self.update, 1.0 / fps)
def update(self, dt):
ret, frame = self.capture.read()
if ret:
# convert it to texture
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')
# display image from the texture
self.texture = image_texture
class CamApp(App):
def build(self):
self.capture = cv2.VideoCapture('stream address removed for stack overflow')
self.my_camera = KivyCamera(capture=self.capture, fps=30)
return self.my_camera
def on_stop(self):
#without this, app will not exit even if the window is closed
self.capture.release()
if __name__ == '__main__':
CamApp().run()
然而,这仅使用 .py。我希望能够使用 kv 语言创建 KivyCamera 实例并为每个实例设置不同的 capture
值。
例如:
BoxLayout:
orientation: 'horizontal'
KivyCamera:
capture: 'myvalue'
pos_hint: {'left': 1}
KivyCamera:
capture: 'anothervalue'
pos_hint: {'right': 1}
您可以将属性设置为 fps 和源(索引、文件名等)而不是 VideoCapture:
main.py
from kivy.app import App
from kivy.uix.image import Image
from kivy.clock import Clock
from kivy.graphics.texture import Texture
from kivy.properties import ObjectProperty, NumericProperty
import cv2
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
class CamApp(App):
pass
if __name__ == "__main__":
CamApp().run()
cam.kv
BoxLayout:
orientation: 'horizontal'
KivyCamera:
source: "stream address removed for stack overflow"
我有 2 到 4 个 rtsp 流,我想在 Kivy 的框布局中显示,但我似乎无法弄清楚如何使用 kv 语言来实现这一点。我可以使用此代码显示一个摄像头:
class KivyCamera(Image):
def __init__(self, capture, fps, **kwargs):
super(KivyCamera, self).__init__(**kwargs)
self.capture = capture
Clock.schedule_interval(self.update, 1.0 / fps)
def update(self, dt):
ret, frame = self.capture.read()
if ret:
# convert it to texture
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')
# display image from the texture
self.texture = image_texture
class CamApp(App):
def build(self):
self.capture = cv2.VideoCapture('stream address removed for stack overflow')
self.my_camera = KivyCamera(capture=self.capture, fps=30)
return self.my_camera
def on_stop(self):
#without this, app will not exit even if the window is closed
self.capture.release()
if __name__ == '__main__':
CamApp().run()
然而,这仅使用 .py。我希望能够使用 kv 语言创建 KivyCamera 实例并为每个实例设置不同的 capture
值。
例如:
BoxLayout:
orientation: 'horizontal'
KivyCamera:
capture: 'myvalue'
pos_hint: {'left': 1}
KivyCamera:
capture: 'anothervalue'
pos_hint: {'right': 1}
您可以将属性设置为 fps 和源(索引、文件名等)而不是 VideoCapture:
main.py
from kivy.app import App
from kivy.uix.image import Image
from kivy.clock import Clock
from kivy.graphics.texture import Texture
from kivy.properties import ObjectProperty, NumericProperty
import cv2
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
class CamApp(App):
pass
if __name__ == "__main__":
CamApp().run()
cam.kv
BoxLayout:
orientation: 'horizontal'
KivyCamera:
source: "stream address removed for stack overflow"