55 votes

Affichage du flux d'une webcam à l'aide d'opencv et de python

J'ai essayé de créer un programme simple avec python qui utilise opencv pour obtenir un flux vidéo de ma webcam et l'afficher sur l'écran.

Je sais que je suis en partie là parce que la fenêtre est créée et que la lumière de ma webcam s'allume, mais il semble que rien ne s'affiche dans la fenêtre. J'espère que quelqu'un pourra m'expliquer ce que je fais mal.

import cv

cv.NamedWindow("w1", cv.CV_WINDOW_AUTOSIZE)
capture = cv.CaptureFromCAM(0)

def repeat():

    frame = cv.QueryFrame(capture)
    cv.ShowImage("w1", frame)

while True:
    repeat()

Dans un autre ordre d'idées, j'ai remarqué que ma webcam change parfois son numéro d'index dans cv.CaptureFromCAM et que parfois je dois mettre 0, 1 ou 2 même si je n'ai qu'une seule caméra connectée et que je ne l'ai pas débranchée (je le sais parce que la lumière ne s'allume pas à moins que je change l'index). Existe-t-il un moyen de faire en sorte que python détermine l'index correct ?

merci

Mitch

75voto

sastanin Points 16061

Une mise à jour pour montrer comment le faire dans les versions récentes d'OpenCV :

import cv2

cv2.namedWindow("preview")
vc = cv2.VideoCapture(0)

if vc.isOpened(): # try to get the first frame
    rval, frame = vc.read()
else:
    rval = False

while rval:
    cv2.imshow("preview", frame)
    rval, frame = vc.read()
    key = cv2.waitKey(20)
    if key == 27: # exit on ESC
        break
cv2.destroyWindow("preview")

Cela fonctionne dans OpenCV-2.4.2 pour moi.

41voto

Matt Boehm Points 1162

Essayez d'ajouter la ligne c = cv.WaitKey(10) au bas de votre repeat() méthode.

Cela permet d'attendre pendant 10 ms que l'utilisateur saisisse une touche. Même si vous n'utilisez pas du tout la touche, mettez ceci. Je pense qu'il y avait juste besoin d'un certain délai, alors time.sleep(10) peut également fonctionner.

En ce qui concerne l'indice de la caméra, vous pourriez faire quelque chose comme ceci :

for i in range(3):
    capture = cv.CaptureFromCAM(i)
    if capture: break

Cela permettra de trouver l'index du premier périphérique de capture "fonctionnel", du moins pour les index de 0 à 2. Il est possible qu'il y ait plusieurs périphériques dans votre ordinateur reconnus comme des périphériques de capture corrects. Le seul moyen que je connaisse pour confirmer que vous avez le bon est de regarder manuellement votre lumière. Peut-être obtenir une image et vérifier ses propriétés ?

Pour ajouter une invite à l'utilisateur dans le processus, vous pouvez lier une touche au changement de caméra dans votre boucle de répétition :

import cv

cv.NamedWindow("w1", cv.CV_WINDOW_AUTOSIZE)
camera_index = 0
capture = cv.CaptureFromCAM(camera_index)

def repeat():
    global capture #declare as globals since we are assigning to them now
    global camera_index
    frame = cv.QueryFrame(capture)
    cv.ShowImage("w1", frame)
    c = cv.WaitKey(10)
    if(c=="n"): #in "n" key is pressed while the popup window is in focus
        camera_index += 1 #try the next camera index
        capture = cv.CaptureFromCAM(camera_index)
        if not capture: #if the next camera index didn't work, reset to 0.
            camera_index = 0
            capture = cv.CaptureFromCAM(camera_index)

while True:
    repeat()

Avis de non-responsabilité : je n'ai pas testé cette méthode, elle peut donc comporter des bogues ou ne pas fonctionner, mais elle peut au moins vous donner une idée de solution de contournement.

8voto

TinBane Points 86

Si vous n'avez qu'une seule caméra, ou si vous ne vous souciez pas de savoir quelle caméra est la bonne, alors utilisez "-1" comme index. Par exemple, pour votre exemple capture = cv.CaptureFromCAM(-1) .

1voto

user808996 Points 54

Essayez ceci, c'est simple, mais je n'ai pas encore trouvé une façon élégante de sortir.

import cv2.cv as cv
import time

cv.NamedWindow("camera", 0)

capture = cv.CaptureFromCAM(0)

while True:
    img = cv.QueryFrame(capture)
    cv.ShowImage("camera", img)
    if cv.WaitKey(10) == 27:
        break
cv.DestroyAllWindows()

0voto

Victor S Points 1615

Cela n'a pas fonctionné pour moi, mais le Gist suivant était un "jeu de copier/coller". https://gist.github.com/2130079

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X