He podido solucionar este problema iterando sobre los índices de la cámara web hasta que la lectura de que la cámara ya no devuelve nada:
index = 0
arr = []
while True:
cap = cv2.VideoCapture(index)
if not cap.read()[0]:
break
else:
arr.append(index)
cap.release()
index += 1
return arr
Este método devuelve una lista de todos los índices que devuelven algo cuando se leen; Estoy seguro de que se puede mejorar, pero casi nunca hay más de unas pocas cámaras web y funciona bastante rápido.
Excelente respuesta de @Patrick, pero me gustaría mejorarla y aún no puedo comentar.
Creo que la configuración de Patrick asume que las cámaras no tienen índices vacíos entre ellas. Pero en mi caso, mi cámara integrada estaba en el índice 0 y la cámara web USB estaba en el índice 2. Entonces, "if not cap.read()[0]" salió del ciclo while en el índice 1, sin atrapar nunca a los demás. . Tenemos que especificar cuántos índices estamos dispuestos a revisar y verificar, y simplemente no agregar los que son nulos.
def returnCameraIndexes():
# checks the first 10 indexes.
index = 0
arr = []
i = 10
while i > 0:
cap = cv2.VideoCapture(index)
if cap.read()[0]:
arr.append(index)
cap.release()
index += 1
i -= 1
return arr
Esto me dio con éxito los índices que necesito. Nuevamente, ¡gracias a Patrick por el diseño!
Este es un problema general de OpenCV, como puede ver a continuación. Parece que solo la cámara integrada o la primera USB (solo si no tiene una cámara integrada) funciona en OpenCV:
Cómo usar una cámara con OpenCV
No se puede acceder a la cámara web USB a través de OpenCV, Cygwin
Captura de OpenCV desde USB no iSight (OSX)
Actualmente, no hay forma de extraer la cantidad de cámaras, como se indica en esta solicitud de función:
https://code.ros.org/trac/opencv/ticket/935
Es posible crear una lista de cámaras sin utilizar cap.read().
import cv2
index = 0
arr = []
while True:
cap = cv2.VideoCapture(index)
try:
if cap.getBackendName()=="MSMF":
arr.append(index)
except:
break
cap.release()
index += 1
print(arr)