环境:ubuntu18.04, python3.6,opencv3.4.10
笔记本自带摄像头和插入的USB摄像头
摄像头设备如下
~$ ll /dev/video*
crw-rw----+ 1 root video 81, 0 5月 15 17:44 /dev/video0
crw-rw----+ 1 root video 81, 1 5月 15 17:44 /dev/video1
crw-rw----+ 1 root video 81, 2 5月 15 17:44 /dev/video2
crw-rw----+ 1 root video 81, 3 5月 15 17:44 /dev/video3
crw-rw----+ 1 root video 81, 4 5月 15 15:23 /dev/video4
crw-rw----+ 1 root video 81, 5 5月 15 15:23 /dev/video5
安装opencv 3.4.10
1. 系统自带的opencv版本4.1.1
2. 卸载opencv
3. 下载opencv 3.4.10 源码和opencv_contrib-3.4.10
4. 解压,编译
5. 查看版本pkg-config --modversion opencv正常
6. python打开图片,视频没问题,打开camera 报错:
读取摄像头视频代码
import cv2
cap = cv2.VideoCapture(0)
while True:
ret, frame = cap.read()
cv2.imshow("camera", frame)
if cv2.waitKey(10) & 0xff == ord('q'):
break
错误 1:Cannot identify device ‘/dev/video0’.
[ WARN:0] OpenCV | GStreamer warning: Embedded video playback halted; module v4l2src0 reported: Cannot identify device '/dev/video0'.
[ WARN:0] OpenCV | GStreamer warning: unable to start pipeline
[ WARN:0] OpenCV | GStreamer warning: GStreamer: pipeline have not been created
解决: 安装 opencv-python
pip3 install opencv-python -i https://pypi.douban.com/simple
继续运行又提示错误:
错误2:can’t open camera by index
[ WARN:0] global /io/opencv/modules/videoio/src/cap_v4l.cpp (887) open VIDEOIO(V4L2:/dev/video0): can't open camera by index
解决: 将设备号改成-1可以打开笔记本自带摄像头,但不知道怎么打开usb摄像头
cv2.VideoCapture(-1)
错误3:关于摄像头设备号
网上很多说要 sudo modprobe bcm2835-v4l2,但是我这里执行会报错,这个是因为v4l2驱动不同的问题, bcm2835这个是树莓派的:
modprobe: FATAL: Module bcm2835-v4l2 not found in directory /lib/modules/5.3.0-51-generic
modprobe会去/lib/modules/目录下找对应的ko,找不到时就会提示错误
搜索我的电脑/lib/modules/目录
find /lib/modules/ -name "*v4l2*.ko"
发现相关的ko
/lib/modules/5.3.0-51-generic/kernel/drivers/media/v4l2-core/v4l2-mem2mem.ko
/lib/modules/5.3.0-51-generic/kernel/drivers/media/v4l2-core/v4l2-flash-led-class.ko
/lib/modules/5.3.0-51-generic/kernel/drivers/media/v4l2-core/v4l2-common.ko
/lib/modules/5.3.0-51-generic/kernel/drivers/media/v4l2-core/v4l2-dv-timings.ko
/lib/modules/5.3.0-51-generic/kernel/drivers/media/v4l2-core/v4l2-fwnode.ko
/lib/modules/5.3.0-51-generic/kernel/drivers/media/i2c/adv7511-v4l2.ko
/lib/modules/5.3.0-51-generic/kernel/drivers/media/common/v4l2-tpg/v4l2-tpg.ko
/lib/modules/5.3.0-51-generic/kernel/drivers/media/common/videobuf2/videobuf2-v4l2.ko
/lib/modules/5.0.0-37-generic/kernel/drivers/media/v4l2-core/v4l2-mem2mem.ko
/lib/modules/5.0.0-37-generic/kernel/drivers/media/v4l2-core/v4l2-flash-led-class.ko
/lib/modules/5.0.0-37-generic/kernel/drivers/media/v4l2-core/v4l2-common.ko
/lib/modules/5.0.0-37-generic/kernel/drivers/media/v4l2-core/v4l2-dv-timings.ko
/lib/modules/5.0.0-37-generic/kernel/drivers/media/v4l2-core/v4l2-fwnode.ko
/lib/modules/5.0.0-37-generic/kernel/drivers/media/i2c/adv7511-v4l2.ko
/lib/modules/5.0.0-37-generic/kernel/drivers/media/common/v4l2-tpg/v4l2-tpg.ko
/lib/modules/5.0.0-37-generic/kernel/drivers/media/common/videobuf2/videobuf2-v4l2.ko
此时adv7511-v4l2.ko这个应该是usb摄像头的
sudo modprobe adv7511-v4l2
此时执行以下两条命令打开的都是usb摄像头了
cv2.VideoCapture(-1) # 打开USB摄像头
cv2.VideoCapture(0) # 打开USB摄像头
cv2.VideoCapture(1) # 报错open VIDEOIO(V4L2:/dev/video1): can't open camera by index
可是怎么打开自带的摄像头呢?
用v4l2-ctl --list-devices 看一下摄像头对应的设备号,没有v4l2-ctl,先安装
sudo apt-get install v4l2-ctl
~$ v4l2-ctl --list-devices
ov9734_azurewave_camera: ov9734 (usb-0000:03:00.3-4.2):
/dev/video4
/dev/video5
SN9C5811_AR0130_Car: USB Camera (usb-0000:03:00.4-1):
/dev/video0
/dev/video1
/dev/video2
/dev/video3
发现原来usb摄像头对应了前四个设备号,4,5才是笔记本自带的摄像头
于是使用设备号4打开自带摄像头成功
cv2.VideoCapture(4) # 打开自带摄像头成功
至于为什么一个摄像头对应多个设备号,这是因为现在摄像头都是多功能的,
一般含有两个设备号:一个是Video Capture,一个是Metadata Capture
我的这个usb摄像头因为做行车记录仪使用的,带有GPS定位和计时等功能所以有四个设备号
要使用摄像头的video功能一般使用第一个设备号即可
想要了解为什么会有多个设备号显示可以看一下源代码:
查看摄像头对应多设备号源代码
注:可以使用 --all 查看摄像头的所有信息
使用 --list-formats-ext 获取支持的分辨率和编码格式
v4l2-ctl -d /dev/video0 --all
v4l2-ctl -d /dev/video0 --list-formats-ext
总结
- python需要安装对应的opencv,即opencv_python,一起安装了opencv_contrib_python最好
- modprobe命令用于自动处理可载入模块,设置摄像头设备后相当于默认使用该设备,即cv2.VideoCapture(设备号) 中设备号为负数时调用的摄像头
- ubuntu18.04一个摄像头会对应多个设备号,使用第一个去调取视频