2010-04-08 45 views
53

He estado intentando crear un programa simple con Python que usa OpenCV para obtener un video de mi cámara web y mostrarlo en la pantalla.Mostrar un feed de webcam usando OpenCV y Python

Sé que estoy parcialmente allí porque se creó la ventana y se enciende la luz de la cámara web, pero simplemente no parece mostrar nada en la ventana. Espero que alguien pueda explicar lo que estoy haciendo 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() 

En una nota relacionada, me he dado cuenta de que mi webcam a veces cambia su número de índice en cv.CaptureFromCAM, ya veces tengo que poner en 0, 1 ó 2 a pesar de que sólo tengo una cámara conectada y no he t desenchufó (lo sé porque la luz no se enciende a menos que cambie el índice). ¿Hay alguna manera de que Python determine el índice correcto?

+0

Tuve este problema hace unos meses ... déjame rastrear mi solución al problema. –

Respuesta

41

Intente agregar la línea c = cv.WaitKey(10) en la parte inferior de su método repeat().

Esto espera 10 ms para que el usuario ingrese una clave. Incluso si no está usando la clave en absoluto, póngala. Creo que solo hubo que esperar un poco, por lo que time.sleep(10) también podría funcionar.

En lo que respecta al índice de la cámara, se puede hacer algo como esto:

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

Esto encontrará el índice del primer "trabajo" dispositivo de captura, al menos para los índices de 0-2. Es posible que haya varios dispositivos en su computadora reconocidos como un dispositivo de captura adecuado. La única manera que conozco para confirmar que tienes la correcta es mirando manualmente tu luz. Tal vez obtener una imagen y comprobar sus propiedades?

Para añadir un mensaje para el usuario en el proceso, que podría vincular una clave para cambiar las cámaras en su repetición en bucle:

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

exención de responsabilidad: No he probado esto por lo que puede tener errores o simplemente no funciona , pero podría darle al menos una idea de una solución alternativa.

+0

¡esa pequeña línea de código funcionaba bien! muchas gracias. sin embargo, el código de índice de la cámara no funcionó, independientemente del dispositivo que ve en el índice 0 todavía devuelve verdadero y rompe el ciclo for. este debe ser el motivo por el que tantos ejemplos acabo de mostrar una pantalla negra. ¿Hay alguna manera de determinar qué está en el índice 0 para poder desactivarlo? o alternativamente cambiar la webcam a 0? – Mitch

+0

hmm, no estoy seguro si hay una manera fácil de hacer esto. en lugar de simplemente verificar que la captura no es un Nonetype, podrías escribir un código más complicado para consultar un cuadro y verificar si el cuadro es "todo negro" al muestrear algunos píxeles al azar. Creo que es mejor proporcionar un mensaje que muestre un marco y le pregunte al usuario si quiere esta cámara o si quiere probar la siguiente. –

+0

Eche un vistazo a mi edición anterior si considera utilizar la entrada del usuario para cambiar de cámara. –

7

Si solo tiene una cámara, o si no le importa cuál cámara es la correcta, utilice "-1" como índice. Es decir, para su ejemplo capture = cv.CaptureFromCAM(-1).

0

cambio import cv a import cv2.cv as cv Ver también el cargo here.

68

Una actualización para mostrar cómo hacerlo en las versiones recientes de 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") 
vc.release() 

Funciona en OpenCV-2.4.2 para mí.

+0

Finalmente ... muchas gracias –

+4

Gracias. Una sugerencia: después del ciclo while, agregue: cv2.destroyWindow ("vista previa") – Luke

+8

Otra sugerencia: después del ciclo while, agregue vc.release(). De lo contrario, no podrá volver a ejecutarlo sin eliminar el proceso, ya que el controlador todavía está abierto. –

1

Intente lo siguiente. Es simple, pero aún no he descubierto una forma elegante de salir.

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

Como en el opencv-doc puede obtener imágenes de vídeo de una cámara que está conectada a su ordenador siguiendo código.

import numpy as np 
import cv2 
cap = cv2.VideoCapture(0) 
while(True): 
    # Capture frame-by-frame 
    ret, frame = cap.read() 
    # Our operations on the frame come here 
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) 
    # Display the resulting frame 
    cv2.imshow('frame',gray) 
    if cv2.waitKey(1) & 0xFF == ord('q'): 
     break 
# When everything done, release the capture 
cap.release() 
cv2.destroyAllWindows() 

Puede cambiar cap = cv2.VideoCapture(0) índice a partir de 0 a 1 para acceder a la segunda cámara.
Probado en opencv-3.2.0