我有一个Kivy小部件,我想充当占位符,从网络摄像头进行实时预览。我已经弄清楚了网络摄像头流部分,但我无法获得流来填充空的图像小部件(假设我甚至应该使用图像小部件而不是其他东西)。
为了记录,我没有使用相机小工具,因为它不适用于不是USB网络摄像头的Raspberry Pi相机。
以下是我的Camera Widget类的代码:
class CV2Camera(BoxLayout):
def __init__(self, **kwargs):
super(CV2Camera, self).__init__(**kwargs)
self.vs = WebcamVideoStream(src=0).start()
def _finish_init(self, dt):
Clock.schedule_interval(self.update, .05)
def update(self, dt):
self.image = self.vs.read()
self.image = imutils.resize(self.image, width=1080)
self.image = np.fliplr(self.image)
self.video_texture = Texture.create(size=(self.image.shape[1], self.image.shape[0]), colorfmt='bgr')
self.video_texture.blit_buffer(self.image.tostring(), colorfmt='bgr', bufferfmt='ubyte')
self.video_panel = self.ids['camera_preview']
with self.video_panel.canvas as canvas:
Rectangle(texture=self.video_texture, pos=self.video_panel.pos, size=self.video_panel.size)
这是我的布局声明:
<CV2Camera>
canvas.before:
PushMatrix
canvas.after:
PopMatrix
<PhotoBooth>:
Screen:
name: 'screen1'
GridLayout:
cols: 2
orientation: 'horizontal'
FloatLayout:
size_hint: 4, 1
CV2Camera:
id: camera
orientation: 'horizontal'
Image:
id: camera_preview
GridLayout:
cols: 1
Button:
text: "<-Previous Frame"
Button:
text: "Next Frame->"
Button:
text: "Take Picture!"
on_press: root.capture()
这段代码运行正常,但我得到的是一个灰色方块,我的图像/相机预览应该显示出来。我对Kivy的架构很陌生,但是网络上的例子(例如this SO thread和this Github project)似乎表明这应该有效。感谢。
答案 0 :(得分:1)
我认为我没有明确的解决方案,但有些言论/问题可能会有所帮助。
我不认为你需要在每次更新时重新创建纹理和矩形,你应该能够在__init__
中创建纹理和画布指令,并在每次更新时执行blit_buffer部分。
我没有看到对_finish_init
的任何电话。是应该用start()
方法调用吗?另外,您真的想在start()
属性中设置vs
的结果,而不是WebcamVideoFrame
对象本身吗? (好吧,它实际上会返回self,如果我可以假设它是你使用的代码https://github.com/jrosebr1/imutils/tree/master/imutils/video)
您当然可以使用<CV2Camera>
规则中的画布说明来获取您的(目前至少在您放在此处的代码中的错误信息)。
显然,您应该可以使用self.vs.grabbed
检查是否正确读取了流。
你不需要使用Image
,任何Widget
都有一个kivy画布,并在其上创建一个矩形,以显示纹理应该没有问题,假设图像被正确编码/转换)。