全景与事件相机
概述
全景相机和事件相机是两类非传统视觉传感器。全景相机提供360度全方位视野,事件相机以异步方式捕捉亮度变化事件。两者在机器人感知中有独特的应用价值。
全景相机
360度视觉的价值
全景视觉为机器人提供无死角的环境感知:
- 全方位障碍物检测:不需要多个相机拼接
- 视觉SLAM:更多特征点、更鲁棒的跟踪
- 场景理解:一次拍摄获取完整环境信息
- 远程操控:操作员可以自由查看任意方向
全景相机类型
| 类型 | 原理 | FOV | 分辨率损失 | 代表 |
|---|---|---|---|---|
| 双鱼眼拼接 | 两个鱼眼镜头背靠背 | 360°x360° | 中 | Ricoh Theta, Insta360 |
| 多相机阵列 | 多个相机环形排列 | 360°x~120° | 低 | Ladybug, 自动驾驶方案 |
| 折反射 | 曲面反射镜+普通相机 | 360°x~60° | 高 | 学术用 |
| 单鱼眼 | 超广角镜头 | ~190° | 中 | 避障用鱼眼 |
常见全景相机产品
Ricoh Theta Z1
| 参数 | 值 |
|---|---|
| 传感器 | 2x 1" CMOS |
| 照片分辨率 | 6720 x 3360 (23MP) |
| 视频分辨率 | 3840 x 1920 @30fps |
| 接口 | USB Type-C / WiFi |
| 特色 | RAW拍摄、插件系统 |
| 价格 | ~$1000 |
Insta360 X4
| 参数 | 值 |
|---|---|
| 传感器 | 2x 1/2" CMOS |
| 照片分辨率 | 11520 x 5760 (72MP) |
| 视频分辨率 | 5.7K @60fps / 8K @30fps |
| 防水 | 10m |
| 特色 | FlowState防抖、AI编辑 |
| 价格 | ~$500 |
鱼眼镜头
鱼眼镜头通过极大的FOV(通常>180度)实现超广角成像。
鱼眼投影模型
| 投影模型 | 公式 | 特点 |
|---|---|---|
| 等距投影 | \(r = f\theta\) | 角度线性映射 |
| 等面积投影 | \(r = 2f\sin(\theta/2)\) | 保面积 |
| 立体投影 | \(r = 2f\tan(\theta/2)\) | 保形 |
| 正交投影 | \(r = f\sin\theta\) | 物理极限 |
其中 \(r\) 是像素到中心的距离,\(\theta\) 是入射角,\(f\) 是焦距。
鱼眼去畸变(Dewarping)
import cv2
import numpy as np
# 鱼眼标定参数
K = np.array([[fx, 0, cx], [0, fy, cy], [0, 0, 1]])
D = np.array([k1, k2, k3, k4]) # 鱼眼畸变系数
# 方法1: 去畸变为针孔图像
new_K = cv2.fisheye.estimateNewCameraMatrixForUndistortRectify(
K, D, (w, h), np.eye(3), balance=0.0 # 0=裁剪, 1=保留全部
)
map1, map2 = cv2.fisheye.initUndistortRectifyMap(
K, D, np.eye(3), new_K, (w, h), cv2.CV_16SC2
)
undistorted = cv2.remap(fisheye_img, map1, map2, cv2.INTER_LINEAR)
# 方法2: 等距柱面投影(用于全景拼接)
def fisheye_to_equirectangular(fisheye_img, K, D, output_size=(1920, 960)):
out_w, out_h = output_size
# 生成等距柱面坐标
lon = np.linspace(-np.pi, np.pi, out_w)
lat = np.linspace(-np.pi/2, np.pi/2, out_h)
lon_grid, lat_grid = np.meshgrid(lon, lat)
# 球面坐标转笛卡尔
x = np.cos(lat_grid) * np.sin(lon_grid)
y = np.sin(lat_grid)
z = np.cos(lat_grid) * np.cos(lon_grid)
# 投影到鱼眼图像
theta = np.arctan2(np.sqrt(x**2 + y**2), z)
phi = np.arctan2(y, x)
r = K[0,0] * theta # 等距投影
u = r * np.cos(phi) + K[0,2]
v = r * np.sin(phi) + K[1,2]
map_x = u.astype(np.float32)
map_y = v.astype(np.float32)
return cv2.remap(fisheye_img, map_x, map_y, cv2.INTER_LINEAR)
全景视觉在机器人中的应用
全景SLAM
全景相机的宽FOV提供更多特征点和更大的旋转容忍度:
- ORB-SLAM3:支持鱼眼相机模型
- OpenVSLAM:支持等距柱面投影
- 优势:旋转时仍有大量特征点跟踪
环视系统(自动驾驶)
前方相机 (鱼眼)
│
┌────┴────┐
│ 车 辆 │
左相机──┤ ├──右相机
(鱼眼) │ 俯视图 │ (鱼眼)
└────┬────┘
│
后方相机 (鱼眼)
4个鱼眼相机拼接 → 360°鸟瞰图(BEV)
事件相机
工作原理
传统相机以固定帧率输出完整图像,而事件相机(Event Camera / Dynamic Vision Sensor, DVS)的每个像素独立异步地响应亮度变化:
当像素 \((x, y)\) 的对数亮度变化超过阈值 \(C\) 时,产生一个事件:
\[
e = (x, y, t, p) \quad \text{当} \quad |\log I(x,y,t) - \log I(x,y,t-\delta t)| \geq C
\]
其中:
- \((x, y)\):像素坐标
- \(t\):时间戳(μs精度)
- \(p \in \{+1, -1\}\):极性(亮度增加/减少)
传统相机 (帧):
时间 ─→ [帧1][帧2][帧3][帧4] ... 固定30/60fps
全部像素同步输出
事件相机 (事件流):
时间 ─→ · ·· · ··· ·· · ··· · · ... 异步、稀疏
只有亮度变化的像素产生事件
核心优势
| 特性 | 传统相机 | 事件相机 |
|---|---|---|
| 时间分辨率 | 10-30ms(帧间隔) | 1μs(事件级) |
| 动态范围 | 60-70dB | >120dB |
| 运动模糊 | 有(帧内积分) | 无(异步事件) |
| 数据量 | 大(全帧) | 小(稀疏事件) |
| 功耗 | 较高 | 低(按需输出) |
| 冗余数据 | 大量静态区域 | 几乎无冗余 |
代表性产品
iniVation DAVIS346
| 参数 | 值 |
|---|---|
| 分辨率 | 346 x 260 |
| 事件带宽 | 12M events/s |
| 动态范围 | >120dB |
| 延迟 | <1μs |
| 特色 | 事件+帧同步输出(DAVIS = DVS + APS) |
| 接口 | USB 3.0 |
| 价格 | ~$5000 |
Prophesee EVK4
| 参数 | 值 |
|---|---|
| 分辨率 | 1280 x 720 (HD) |
| 事件带宽 | >1G events/s |
| 像素大小 | 4.86μm |
| 动态范围 | >120dB |
| 延迟 | ~100ns |
| 价格 | ~$3000 |
对比
| 特性 | DAVIS346 | Prophesee EVK4 |
|---|---|---|
| 分辨率 | 346x260 | 1280x720 |
| 帧输出 | 有(APS) | 无 |
| 事件带宽 | 12M/s | >1G/s |
| 生态 | DV软件 | Metavision SDK |
| 适合 | 研究原型 | 高性能应用 |
事件数据表示
事件流需要转换为适合处理的格式:
import numpy as np
# 原始事件数据
# events: Nx4 array [x, y, timestamp, polarity]
def events_to_frame(events, height, width, time_window):
"""事件累积为帧(时间窗口内的事件直方图)"""
frame = np.zeros((height, width, 2)) # 正极性和负极性
for x, y, t, p in events:
if p > 0:
frame[int(y), int(x), 0] += 1
else:
frame[int(y), int(x), 1] += 1
return frame
def events_to_voxel_grid(events, height, width, num_bins=5):
"""事件体素网格(时间维度离散化)"""
voxel = np.zeros((num_bins, height, width))
t_min, t_max = events[:, 2].min(), events[:, 2].max()
t_norm = (events[:, 2] - t_min) / (t_max - t_min + 1e-6)
for x, y, t_n, p in zip(events[:, 0], events[:, 1], t_norm, events[:, 3]):
bin_idx = min(int(t_n * num_bins), num_bins - 1)
voxel[bin_idx, int(y), int(x)] += p
return voxel
def events_to_surface(events, height, width, tau=30000):
"""时间表面(Time Surface)"""
surface = np.zeros((2, height, width))
for x, y, t, p in events:
pol = 0 if p > 0 else 1
surface[pol, int(y), int(x)] = t
# 归一化(指数衰减)
t_now = events[-1, 2]
surface = np.exp(-(t_now - surface) / tau)
surface[surface < np.exp(-1)] = 0 # 截断
return surface
事件相机在机器人中的应用
高速避障
\[
\text{反应时间} = t_{\text{sensor}} + t_{\text{process}} + t_{\text{actuator}}
\]
事件相机将 \(t_{\text{sensor}}\) 从~33ms(30fps)降低到~1μs,对高速无人机至关重要。
视觉里程计
事件驱动的VIO(Visual-Inertial Odometry):
- EVO:Event-based Visual Odometry
- ESVO:Event-based Stereo Visual Odometry
- 优势:快速运动时不会丢失跟踪(无运动模糊)
光流估计
事件天然编码运动信息,适合光流估计:
\[
\frac{\partial \log I}{\partial t} = -\nabla(\log I) \cdot \mathbf{v}
\]
其中 \(\mathbf{v} = (v_x, v_y)\) 是光流。
HDR场景感知
- 工厂中明暗交替的场景
- 隧道出入口
- 焊接/切割等强光场景
事件相机的挑战
| 挑战 | 说明 | 研究方向 |
|---|---|---|
| 算法生态不成熟 | 传统CV算法不适用 | 事件驱动算法研究 |
| 分辨率低 | 最高720p | 新型传感器设计 |
| 成本高 | >$3000 | 量产降价(预计) |
| 静态场景无输出 | 需要运动才有事件 | 与帧相机融合(DAVIS) |
| 噪声 | 暗电流产生假事件 | 时空滤波 |
| 数据量大(高速) | 百万事件/秒 | 硬件加速处理 |
组合方案
鱼眼 + 事件
鱼眼事件相机:
- 宽FOV(>180°)
- 微秒级时间分辨率
- 用途:高速无人机全方位感知
全景 + 深度
全景RGB-D:
- 4个RealSense D435i环形排列
- 360°深度感知
- 用途:服务机器人全方位导航
DAVIS + 传统相机
事件+帧融合:
- DAVIS346输出同步的事件和帧
- 帧用于纹理丰富的场景
- 事件用于高速运动和HDR场景
- 用途:鲁棒的视觉SLAM
小结
- 全景相机提供360度感知,消除视野盲区
- 鱼眼镜头需要专门的投影模型和去畸变处理
- 事件相机以μs时间分辨率和>120dB动态范围突破传统相机限制
- 事件数据需要特殊的表示方法(体素网格、时间表面等)
- 事件相机在高速场景和极端光照下优势明显
- 两者都在快速发展中,成本和生态逐步改善
参考资料
- Gallego, G., et al. "Event-based Vision: A Survey" IEEE TPAMI, 2022
- Scaramuzza, D. "Event Cameras: A New Paradigm for Robot Perception" (tutorial)
- iniVation DV Software: https://docs.inivation.com/
- Prophesee Metavision SDK: https://docs.prophesee.ai/
- OpenCV Fisheye Camera Model: https://docs.opencv.org/