Trouble with slow kivy app to view webcam in real time

Viewed 243

I am trying to make a kivy app to display images grabbed from a webcam in real time. It works, but is slow, and I am wondering in anyone knows how to fix this or knows of a different method to use. By slow, I mean that there is a large delay between successive images being displayed.

The code is simple, just consists of a rectangle on which the image grabbed from a camera is displayed via texture.blit_buffer . There is a 'Play' button to start and stop image display.

I have scheduled the texture on the rectangle to be updated every 0.02s, and using pythons time module I was able to time the execution of the function that updates the texture. The function is called and executes about every 0.02s, so the issue is not the function itself being slow. This is where I am hung up. What else is causing this to update the displayed image so slowly?

Anyway, here is the .py file

import numpy as np
import cv2

from kivy.app import App
from kivy.uix.widget import Widget 

from kivy.core.window import Window 
from kivy.uix.button import Button
from kivy.graphics.texture import Texture
from kivy.clock import Clock

from kivy.properties import NumericProperty

import time


class WebcamGUI(Widget):

    IsPlaying = False
    Event = None

    Size_x = 640
    Size_y = 480

    texture = Texture.create(size=(Size_x,Size_y),colorfmt='bgr')
    frame = np.ones(shape=[Size_x, Size_y, 3], dtype=np.uint8)
    data = frame.tostring()
    texture.blit_buffer(data, colorfmt='bgr', bufferfmt='ubyte')

    cap = cv2.VideoCapture(0)

    t = time.time()

    def GetFrame(self,dt):
        ret, frame = self.cap.read()
        frame1 = cv2.flip(frame, 0)
        data = frame1.tostring()
        self.texture.blit_buffer(data, colorfmt='bgr', bufferfmt='ubyte')
        print(time.time()-self.t)
        self.t = time.time()

    def Play(self):
        self.IsPlaying = not self.IsPlaying
        if self.IsPlaying:
            self.Event = Clock.schedule_interval(self.GetFrame,0.02)
        else:
            self.Event.cancel()

class WebcamGUIApp(App):
    def build(self):
        GUI = WebcamGUI()
        return GUI

    def on_stop(self):
        self.cap.release()

if __name__ == '__main__':
    Window.fullscreen = False
    WebcamGUIApp().run()
    cv2.destroyAllWindows()

Here is the .kv file:

#:kivy 1.0.9

<WebcamGUI>:
    canvas:
        Rectangle:
            pos: 100,100
            size: self.Size_x,self.Size_y   
            texture: self.texture   
    ToggleButton:
        pos: (10,10)
        size: 100,25
        text: "Play"
        on_press: root.Play()
0 Answers
Related