rgb相机

RGB相机使用


参数:对焦,曝光,曝光时间,增益,白平衡。

**对焦:**rgb相机一般是自动对焦,如果我们自动对焦,就会导致内参改变,对后续跟踪会产生很大影响。

**曝光:**如果自动曝光,就是会导致相邻的同一个物体亮度剧烈变化,这会破坏描述子的一致性以及直接法的最基本的光度不变假设。

曝光时间:时间太短,会比较暗,需要增益来放大亮度,这样噪声也会被放大;时间太长,会导致运动模糊,这个对识别和提取特征点影响比较大。

**增益:**曝光时间缩短后画面会变暗,需要提高 Gain 来补偿亮度。虽然会引入噪点,但在 SLAM 中,噪点比模糊稍微好处理一点

白平衡:这个会导致色温变化而影响图像的特征匹配,目前不确定是不是会影响识别。


这个可以通过opencv来控制,linux可以通过v4l2-ctl控制。

安装命令:sudo apt-get install v4l-utils

为了确定设备被挂载在那里,需要查看设备被挂载在哪里:

v4l2-ctl --list-devices

查看分辨率

v4l2-ctl -d /dev/video0 --list-formats-ext

查看参数

v4l2-ctl -d /dev/video0 --list-ctrls

下面是我的相机的参数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
User Controls

brightness 0x00980900 (int) : min=-64 max=64 step=1 default=0 value=0
contrast 0x00980901 (int) : min=0 max=100 step=1 default=57 value=57
saturation 0x00980902 (int) : min=0 max=128 step=1 default=80 value=80
hue 0x00980903 (int) : min=-40 max=40 step=1 default=0 value=0
white_balance_automatic 0x0098090c (bool) : default=1 value=1
gamma 0x00980910 (int) : min=72 max=255 step=1 default=214 value=214
gain 0x00980913 (int) : min=0 max=100 step=1 default=0 value=0
power_line_frequency 0x00980918 (menu) : min=0 max=2 default=1 value=1
white_balance_temperature 0x0098091a (int) : min=2300 max=6500 step=1 default=5000 value=5000 flags=inactive
sharpness 0x0098091b (int) : min=1 max=64 step=1 default=32 value=32
backlight_compensation 0x0098091c (int) : min=0 max=1 step=1 default=0 value=0

Camera Controls

auto_exposure 0x009a0901 (menu) : min=0 max=3 default=3 value=3
exposure_time_absolute 0x009a0902 (int) : min=1 max=5000 step=1 default=300 value=300 flags=inactive
focus_absolute 0x009a090a (int) : min=0 max=1023 step=1 default=192 value=433 flags=inactive
focus_automatic_continuous 0x009a090c (bool) : default=1 value=1
zoom_absolute 0x009a090d (int) : min=0 max=100 step=1 default=0 value=0
zoom_continuous 0x009a090f (int) : min=0 max=0 step=0 default=0 value=0

其中,目前的 focus_absolute 值是 433,范围是 0-1023。 SLAM 需要焦距固定。我目前还是设置默认值:

v4l2-ctl -d /dev/video0 --set-ctrl=focus_automatic_continuous=0

v4l2-ctl -d /dev/video0 --set-ctrl=focus_absolute=433

需要控制曝光就需要先关闭自动曝光:v4l2-ctl -d /dev/video0 --set-ctrl=auto_exposure=1

然后设置曝光时间:v4l2-ctl -d /dev/video0 --set-ctrl=exposure_time_absolute=100

然后设置增益:v4l2-ctl -d /dev/video0 --set-ctrl=gain=50

接下来就是固定白平衡:

1
2
3
4
5
# 1. 关闭自动白平衡
v4l2-ctl -d /dev/video0 --set-ctrl=white_balance_automatic=0

# 2. 锁定色温 (比如锁定在 5000)
v4l2-ctl -d /dev/video0 --set-ctrl=white_balance_temperature=5000

然后继续上述的命令来查看设置的参数:

v4l2-ctl -d /dev/video0 --list-ctrls


如何查看效果

方法一:使用 ffplay (最推荐,延时低,不篡改参数)
ffplay FFmpeg 的一部分,它非常纯净,只负责播放,不会像某些软件那样自作主张地去重置你的相机参数。

安装 (如果没有的话):

sudo apt install ffmpeg
运行命令: (假设你的设备是 /dev/video0,分辨率是 640x480)

1
2
3
4
# -f video4linux2: 指定 V4L2 驱动
# -input_format mjpeg: 强制使用 MJPG (防止由 YUYV 导致的卡顿)
# -framerate 30: 尝试 30 帧
ffplay -f video4linux2 -input_format mjpeg -video_size 640x480 -framerate 30 /dev/video0

方法二:

既然是做开发的,用代码看最安心。注意: 这个脚本里不要加任何 cap.set() 语句,只负责读,这样才能原汁原味地看到 v4l2-ctl 的设置效果。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import cv2

cap = cv2.VideoCapture(0)

# 1. 强制指定 FourCC 格式 (对应 list-formats-ext 中的 'MJPG')
cap.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc('M', 'J', 'P', 'G'))
# 如果想用 YUYV,就是 cv2.VideoWriter_fourcc('Y', 'U', 'Y', 'V')

# 2. 强制指定分辨率 (对应 Size)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)

# 3. (可选) 强制指定帧率 (对应 Interval)
cap.set(cv2.CAP_PROP_FPS, 30)

# 检查实际生效的格式
actual_fourcc = int(cap.get(cv2.CAP_PROP_FOURCC))
# 解码 FourCC 整数
codec = "".join([chr((actual_fourcc >> 8 * i) & 0xFF) for i in range(4)])
print(f"当前格式: {codec}")

注意,就是虚拟机USB 2.0 协议 往往带不动 640x480 MJPG 30fps 的数据量,导致数据堵在半路。启动虚拟机并连接相机后,在读取图片前,必须执行这行命令。它会告诉 Linux 内核:“忽略这台相机的带宽计算错误,强制读取”。

先卸载旧驱动
1
2
3
4
sudo modprobe -r uvcvideo

# 重新加载,开启 quirks=128 (修复带宽) 和 nodrop=1 (强制不丢包)
sudo modprobe uvcvideo quirks=128 nodrop=1