3、相机传感器基础:从参数到噪声,一次讲透
各位同学,欢迎来到传感器模拟的第三讲。今天咱们聊聊相机传感器——这个在自动驾驶里最常用、也最容易出幺蛾子的传感器。
说实话,我刚接触LGSVL的时候,觉得相机配置不就是填几个数字嘛。后来才发现,每个参数背后都有坑。分辨率设高了,仿真跑不动;设低了,算法又识别不到目标。嗯,咱们今天就把这些参数掰开揉碎了讲。
3.1 相机配置参数详解
打开LGSVL的相机配置界面,你会看到一堆参数。别慌,核心的就这几个:
| 参数 | 说明 | 我的建议值 |
|---|---|---|
| 分辨率 (Resolution) | 图像宽×高,单位像素 | 1920×1080(平衡性能与画质) |
| 视场角 (FOV) | 水平视角范围,单位度 | 60°~90°(视场景而定) |
| 焦距 (Focal Length) | 镜头光学中心到成像面的距离 | 由FOV和传感器尺寸计算得出 |
| 近裁面 (Near Clip) | 相机能看到的最近距离 | 0.1m |
| 远裁面 (Far Clip) | 相机能看到的最远距离 | 1000m |
分辨率这个参数,我踩过坑。有一次为了追求画质,直接上了4K分辨率。结果仿真帧率掉到个位数,车辆控制都卡顿了。后来我学乖了——先跑1080p,等算法调通了再考虑提分辨率。
视场角更有意思。FOV越大,看到的范围越广,但物体变形也越严重。你想想看,用120°的超广角拍路边的行人,那人脸都拉变形了,目标检测算法直接懵圈。我个人习惯,城区道路用80°左右,高速用60°就够了。
这里有个公式要记住:
焦距 = (传感器宽度 / 2) / tan(FOV / 2)
在LGSVL里,你设了FOV,系统会自动算焦距。但如果你要模拟特定型号的相机,就得手动算一下。比如模拟Mobileye的摄像头,它的FOV一般是50°左右。
3.2 RGB图像输出与可视化
配置好相机,接下来就是看图像了。LGSVL支持多种输出格式,最常用的是RGB图像。
代码里怎么拿图像?很简单:
# 在Python中获取相机图像
def on_camera(self, sensor_msg):
# sensor_msg是Image类型
image = sensor_msg.image_data
# 转成numpy数组
img_array = np.frombuffer(image, dtype=np.uint8)
img_array = img_array.reshape((height, width, 3))
# 显示
cv2.imshow("Camera", img_array)
我曾经犯过一个低级错误——忘了图像是BGR格式还是RGB格式。OpenCV默认是BGR,而LGSVL输出的是RGB。直接显示的话,颜色全乱了。后来我加了一行转换代码:
img_rgb = cv2.cvtColor(img_array, cv2.COLOR_RGB2BGR)
嗯,这种坑,踩过一次就记住了。
可视化方面,LGSVL自带的Web UI就能看到实时画面。但我建议你同时开一个独立的显示窗口,方便对比不同参数的效果。我个人习惯是把原始图像、深度图、语义分割图并排显示,一眼就能看出问题。
3.3 相机噪声类型概述
为什么仿真要加噪声?说白了,就是让算法在更真实的环境里训练。你想想看,如果算法只在完美图像上训练,到了真实道路上遇到点雨雾、暗光,直接就罢工了。
常见的相机噪声类型,我列了个表:
| 噪声类型 | 产生原因 | 仿真模拟方法 |
|---|---|---|
| 高斯噪声 | 传感器热噪声、电子噪声 | 添加高斯随机数 |
| 泊松噪声 | 光子到达的随机性 | 根据像素值添加泊松分布噪声 |
| 椒盐噪声 | 像素损坏、传输错误 | 随机将像素设为0或255 |
| 运动模糊 | 车辆运动或抖动 | 卷积核模糊 |
| 镜头畸变 | 镜头光学缺陷 | 径向/切向畸变模型 |
高斯噪声是最基础的。我在做夜间场景仿真时,会把高斯噪声的方差调大一些,模拟低光照下的画质下降。
泊松噪声和像素值有关。亮的地方噪声大,暗的地方噪声小。这个更接近真实物理过程。LGSVL里有个"Photon Noise"选项,就是模拟这个的。
运动模糊这个,我印象特别深。有一次仿真里车辆高速行驶,相机图像清晰得不像话。我加了运动模糊之后,目标检测的准确率直接掉了15%。这才对嘛,真实情况就是这样。
在LGSVL里配置噪声,可以在相机配置的"Noise"标签页里操作。每个噪声类型都有对应的参数滑块,调起来很方便。但我建议你通过代码来控制,这样方便做批量实验。
好了,这一章的内容就到这儿。下一章咱们会深入讲每种噪声的具体实现,包括代码怎么写、参数怎么调。到时候我会分享一些我在实际项目中踩过的坑,保证让你少走弯路。