WSL2环境下OpenCV调用主机摄像头遇select() timeout错误求助
问题:WSL2中OpenCV读取罗技C910摄像头出现select() timeout错误
环境配置
- WSL版本:5.15.90.3-microsoft-standard-WSL2+
- Python版本:Python 3
- OpenCV版本:4.8.0
- 摄像头:罗技C910(Bus 001 Device 003: ID 046d:0821 Logitech, Inc. HD Webcam C910)
- 已编译包含USB摄像头驱动的WSL内核,
lsusb可正常识别摄像头,guvcview能正常打开摄像头流
问题现象
运行Python OpenCV代码时,摄像头指示灯亮起后出现如下错误:
[ WARN:0@10.193] global cap_v4l.cpp:1119 tryIoctl VIDEOIO(V4L2:/dev/video0): select() timeout.
随后摄像头指示灯熄灭,程序提示Failed to read frame from video capture.
测试代码
import cv2 # Set the video codec, output file name, and frame rate codec = cv2.VideoWriter_fourcc(*'XVID') output_file = 'output.avi' frame_rate = 30.0 # Set up the video capture object video_capture = cv2.VideoCapture(0) # Check if camera opened successfully if not video_capture.isOpened(): print("Failed to open video capture.") exit(1) # Get the video frame width and height from the capture object frame_width = int(video_capture.get(cv2.CAP_PROP_FRAME_WIDTH)) frame_height = int(video_capture.get(cv2.CAP_PROP_FRAME_HEIGHT)) # Check if resolution retrieval was successful if frame_width == 0 or frame_height == 0: print("Failed to retrieve frame resolution.") video_capture.release() exit(1) # Create a VideoWriter object to save the recorded video video_writer = cv2.VideoWriter( output_file, codec, frame_rate, (frame_width, frame_height)) # Check if VideoWriter was successfully opened if not video_writer.isOpened(): print("Failed to open VideoWriter.") video_capture.release() exit(1) while True: # Capture the video frame by frame ret, frame = video_capture.read() # Break the loop if no frame is captured if not ret: print("Failed to read frame from video capture.") break # Display the captured frame cv2.imshow('frame', frame) # Write the frame to the video file if not video_writer.write(frame): print("Failed to write frame to video file.") break # Break the loop if the 'q' key is pressed if cv2.waitKey(1) == ord('q'): break # Release the video capture and writer objects video_capture.release() video_writer.release() # Close all OpenCV windows cv2.destroyAllWindows()
lsusb输出
~/01_PROJECTS/spiderrobot/source$ lsusb Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub Bus 001 Device 003: ID 046d:0821 Logitech, Inc. HD Webcam C910 Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
解决方法
1. 指定V4L2后端并手动设置摄像头参数
OpenCV可能未正确调用V4L2后端,或默认参数与摄像头不匹配。修改初始化代码,指定后端并设置摄像头支持的分辨率和帧率(可先用v4l2-ctl --list-formats-ext查询摄像头支持的具体参数):
import cv2 video_capture = cv2.VideoCapture(0, cv2.CAP_V4L2) # 示例设置为1280x720 30fps,需匹配摄像头实际支持的参数 video_capture.set(cv2.CAP_PROP_FRAME_WIDTH, 1280) video_capture.set(cv2.CAP_PROP_FRAME_HEIGHT, 720) video_capture.set(cv2.CAP_PROP_FPS, 30)
2. 调整摄像头设备权限
确保当前用户拥有访问摄像头设备的权限:
# 临时赋予权限 sudo chmod 666 /dev/video0 # 永久添加到video组(执行后需重新登录生效) sudo usermod -aG video $USER
3. 增加摄像头启动延迟
摄像头初始化需要时间,在读取帧前添加短暂延迟:
import time time.sleep(2) # 等待摄像头完成初始化
4. 调整摄像头缓冲区大小
通过v4l2-ctl命令调整缓冲区:
v4l2-ctl --set-ctrl=buffer_size=1024000
5. 重新编译或更新OpenCV
确保OpenCV编译时启用了V4L2支持,或更新到最新版本。编译源码时需添加参数:-DWITH_V4L=ON
内容的提问来源于stack exchange,提问作者vorpXuser
相关产品推荐
相关产品推荐

