Forum: PC-Programmierung OpenCV Webcam


von OCV (Gast)


Lesenswert?

Hallo,

ich möchte mit einer Webcam Fotos machen unter der Verwendung von 
OpenCV. Ich habe folgenden Code:

import cv2

capture = cv2.VideoCapture()
capture.open(0)

while True:
    img = capture.read()[1]

    ...

    cv2.imwrite("test.jpg", img)


Nun wird aber immer wieder dasselbe Foto abgespeichert. Was mache ich 
falsch?

von Norbert (Gast)


Lesenswert?

Du möchtest mit: QueryFrame(capture) arbeiten!

von OCV (Gast)


Lesenswert?

QueryFrame(capture): Das ist das alte Interface.

von Norbert (Gast)


Lesenswert?

OCV schrieb:
> QueryFrame(capture): Das ist das alte Interface.

Stimmt, dafür funktioniert es...

Was wieder einmal beweist:
Nicht alles was alt ist, ist automatisch schlecht! ;-)

von OCV (Gast)


Lesenswert?

Das Problem ist dasselbe mit dem alten Interface. Es tritt besonders in 
folgender Konstellation auf:


capture = cv2.VideoCapture()
capture.open(0)

while(1):
    time.pause(2)
    img = capture.read()[1]
    cv2.imwrite("test.jpg", img)


Die Pause repräsentiert andere Befehle, die etwas dauern...


Lösen lässt sich das Problem wie folgt:

capture = cv2.VideoCapture()
capture.open(0)

while(1):
    time.pause(2)
    for i in range(15):
        img = capture.read()[1]
    cv2.imwrite("test.jpg", img)

Jetzt ist das Aufnehmen natürlich sehr lahm.

Ich vermute also, dass das capture.read()[1] immer ein Frame aus irgend 
einem Buffer liest. Kann man den irgendwie per Befehl leeren?

von Vlad T. (vlad_tepesch)


Lesenswert?

warum entkoppelst du nicht einfach das grabbing und die 
Bildverarbeitung?

von OCV (Gast)


Lesenswert?

Hast du eine Idee wie? Hier ist mein Codeaufbau:


# Start Webcam
capture = cv2.VideoCapture()
capture.open(0)
print('Webcam lunched')

# Configure Pins
GPIO.setup(11, GPIO.IN)

while(1):
   # Read Pin
   pin = GPIO.input(11)
   img = capture.read()[1]
   if(pin==False)
      print('Motion detected')
      subprocess.call(["aplay", "Sound/Welcome.wav"])
      # Take photo
      for i in range(15):
         img = capture.read()[1]
      subprocess.call(["aplay", "Sound/Bip.wav"])
      cv2.imwrite("Faces/output.jpg",img)
      print "Captured"





PS: Es gibt noch andere mit demselben Problem. Man muss doch irgendwie 
den Ringpuffer leeren können:

http://stackoverflow.com/questions/2534543/emgucv-opencv-queryframe-slow-buffers

http://opencv-users.1802565.n2.nabble.com/cvGrabFrame-is-not-grabbing-a-frame-as-it-should-td3195192.html

von Vlad T. (vlad_tepesch)


Lesenswert?

OCV schrieb:
> Hast du eine Idee wie? Hier ist mein Codeaufbau:

Klar:
ein thread kümmert sich rein um das grabbing und ein anderer macht die 
verarbeitung.

Man braucht 3 Puffer und 3 Zeiger (grab, exchange, process), die darauf 
zeigen.

Grabber-Thread:
Der grabber holt sich einfach immer ein bild und schreibt inden Puffer, 
auf den grab zeigt. Dannach vertausch er die Inhalte der Zeiger grab und 
exchange.
-->  in exchange steht immer das letzte bild.

Processing-Thread:
Die Verarbeitung vertauscht zu Begin den Inhalt der Zeiger exchange und 
process. und arbeitet dann auf den dahinterliegenden Puffer

Dazu muss man noch austauschen, ob ein neus Bild da war oder nicht. Auch 
kann es nicht schaden zu speichern, welches Bild man da gerade hat und 
wieviele man verloren hat.
Und die Pointer-Austauschvorgänge müssen natürlich durch Mutexe 
geschützt werden.

So würd ichs machen, wenn ich einen low level grabber hätte.
Kenn mich jetzt mit der grabbing-Funktionalität der OCv nicht so gut 
aus, aber die scheint ja schon eine pufferung zu machen.
Vielleicht ist das ganze auch nicht mehr nötig.

Ansonsten weiß ehrlich gesagt noch nicht mal, womit du überhaupt 
programmierst.
Ist das Python? aufm RPi?

OCV schrieb:
> print('Webcam lunched')
ich wette die liegt schwer im Magen?

von Vlad T. (vlad_tepesch)


Lesenswert?

hmm - wenn ich mir deinen Code so ansehe werd ich das gefühl nicht los, 
dass dein Auslesen des 1. Elementes (warum überhaupt [1] und nicht [0]?) 
komisch ist.
kann es sein, dass du statt dem Zugriff ein pop oder sowas machen 
müsstest, was das element auch aus dem Array entfernt? - nur so ein 
Gedanke

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.