Reputation: 13706
I have been using the "grab and retrieve" flow with OpenCV's VideoCapture on linux for a long time. Now migrating the code to Windows 11, it seems with the same USB Webcams that using retrieve is not working:
import sys
import cv2
camera_number = 2
print(f"video output encoding backends available to OpenCV: "
f"{[cv2.videoio_registry.getBackendName(backend) for backend in cv2.videoio_registry.getWriterBackends()]}")
print(f"camera video acquisition backends available to OpenCV: "
f"{[cv2.videoio_registry.getBackendName(backend) for backend in cv2.videoio_registry.getStreamBackends()]}")
video_stream = cv2.VideoCapture(camera_number, cv2.CAP_DSHOW)
if video_stream.isOpened():
print(f"successfully opened camera number {camera_number}")
else:
print(f"\nfailed to open camera number {camera_number}")
sys.exit(1)
print(f"OpenCV is using the following backend library for camera video acquisition: {video_stream.getBackendName()}")
success, image = video_stream.read()
if success:
print('read image succeeded')
else:
print('read image failed')
while video_stream.isOpened():
grabbed = video_stream.grab()
if grabbed:
print('image grab succeeded')
else:
print('image grab failed')
success, image = video_stream.retrieve()
if not success:
raise ValueError(f'image retrieve failed')
This code succeeds up until the retrieve().
Here's the full output:
video output encoding backends available to OpenCV: ['FFMPEG', 'GSTREAMER', 'INTEL_MFX', 'MSMF', 'CV_IMAGES', 'CV_MJPEG']
camera video acquisition backends available to OpenCV: ['FFMPEG', 'GSTREAMER', 'INTEL_MFX', 'MSMF', 'CV_IMAGES', 'CV_MJPEG']
successfully opened camera number 2
OpenCV is using the following backend library for camera video acquisition: DSHOW
read image succeeded
image grab succeeded
Traceback (most recent call last):
line 49, in <module>
raise ValueError(f'image retrieve failed')
ValueError: image retrieve failed
Process finished with exit code 1
As seen above, this is using DSHOW. Notably, none of the backends other than DSHOW seemed to manage to open the Webcam cameras, although the OpenCV API states them as supported.
Enabling the env variable OPENCV_VIDEOIO_DEBUG=1 does not reveal any warnings or errors.
The problem regards USB cameras but not the laptop's in-built camera: switching to camera number 0, the laptop's built-in camera, the same above code seamlessly works and manages to loop on grab and retrieve, but not with any of two Logitech Webcams (Logitech Brio and Logitech C390e) on this Windows 11 laptop.
opencv-python: 4.5.5.62 opencv-contrib-python: 4.5.5.62 winrt: 1.0.21033.1 python: 3.9.10
How would you approach this?
Upvotes: 1
Views: 754
Reputation: 13706
Ok, seems that (not much unlike on Linux) each webcam exposes more than one camera number through the OS, and by choosing one and not the other camera number, give or take a Windows Update bringing in some Logitech software update, it works.
Although both camera numbers manage opening the camera, only one of them enables the full flow. Enumerating the properties of each camera number through code is rough but through trial and error over just two of them camera numbers, it works.
Upvotes: 1