2017-08-29 3 views
0

Ich habe ein Kivy-Widget, das ich als Platzhalter für eine Live-Vorschau von einer Webcam fungieren möchte. Ich habe bereits den Webcam-Stream-Teil herausgefunden, aber ich kann den Stream nicht ganz erreichen, um das leere Image-Widget zu füllen (vorausgesetzt, ich sollte sogar ein Bild-Widget verwenden und nicht etwas anderes).Kivy Widget mit Numpy Image Array Daten aktualisieren

Für das Protokoll, ich bin der Kamera-Widget nicht verwenden, da es mit dem Raspberry Pi Kamera funktioniert nicht gut, die kein USB-Webcam ist. Hier

ist der Code für meine Kamera Widget-Klasse:

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) 

Und hier ist mein Layout Erklärung:

<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() 

Dieser Code läuft gut, aber alles, was ich bekommen ist ein grauer Platz, wo meine Bild/Kamera Vorschau sollte angezeigt werden. Ich bin neu in Kivys Architektur, aber die Beispiele aus dem Internet, die mich hierher gebracht haben (wie this SO thread und this Github project) scheinen darauf hinzudeuten, dass dies funktionieren sollte. Vielen Dank.

+0

haben Sie versucht, mit https://kivy.org/docs/api-kivy.uix.camera.html – PalimPalim

+0

Dank Palim, wie in der oben angegeben, ist die eingebaute in Kivy Kamera-Widget nicht wählen die Raspberry Pi-Kamera "out-of-the-box", und ich habe zu lange gekämpft, um zu versuchen, es sonst ohne Erfolg zum Laufen zu bringen. – John

+0

Entschuldigung, habe nicht sorgfältig genug gelesen. – PalimPalim

Antwort

1

Ich glaube nicht, dass ich hier eine definitive Lösung habe, aber einige Bemerkungen/Fragen, die weiterhelfen können.

  • Ich glaube nicht, dass Sie die Textur und das Rechteck jedes Update neu erstellen müssen, sollten Sie in der Lage sein, die Textur und Leinwand Anweisung in __init__ und nur die in jedem Update blit_buffer Teil tun, um zu erstellen.

  • Ich sehe keinen Anruf an _finish_init. Soll es von der start() Methode oder etwas aufgerufen werden? Möchten Sie das Ergebnis start() im Attribut vs und nicht das Objekt WebcamVideoFrame wirklich festlegen? (ok, es gibt tatsächlich selbst zurück, wenn ich annehmen kann, dass es dieser Code ist, den Sie verwenden

  • Sie können sicherlich Fahrt von Ihrem (derzeit memoriginiert, zumindest in dem Code, den Sie hier setzen), Leinwand Anweisungen in der <CV2Camera> Regel.

  • Anscheinend sollten Sie in der Lage sein zu überprüfen, ob der Strom richtig gelesen wurde self.vs.grabbed.

  • Sie brauchen keine Image zu verwenden, jede Widget hat eine Leinwand in Kivy, und ein Rechteck auf sie zu schaffen, die Textur anzuzeigen, ohne Problem arbeiten soll, wird das Bild unter der Annahme, richtig codiert/konvertierte).

+0

Danke! Das war eine große Hilfe. Ich bin jetzt in der Lage, den blit_buffer zu erhalten, um das Rechteck/die Textur zu füllen. Ich denke, das große Problem war, dass finish_init nie angerufen wurde, aber es gab andere auf dem Weg. Der Puffer scheint nach etwa 30 Sekunden zu verpuffen und zu pixelieren. Vielleicht übertreibe ich es? – John