使用Numpy图像阵列数据更新Kivy Widget

时间:2017-08-29 16:17:26

标签: python-3.x opencv numpy raspberry-pi kivy

我有一个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 threadthis Github project)似乎表明这应该有效。感谢。

1 个答案:

答案 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画布,并在其上创建一个矩形,以显示纹理应该没有问题,假设图像被正确编码/转换)。