项目说明:基于Python的环视系统开发演示
本项目是一个简单、可运行且易于复现的演示,展示如何使用Python开发环视系统。包含相机标定、图像拼接和实时处理等关键步骤。
项目背景
最初在一辆配备AGX Xavier和四个USB鱼眼摄像头的小车上开发(参见img/smallcar.mp4
):
(摄像头分辨率设为640x480,全部使用Python实现)
后期改进并迁移到北汽EU5车型,仍使用Xavier AGX处理,获得更好效果(参见img/car.mp4
):
(EU5版本使用四个960x640分辨率的CSI摄像头,最终环视图像分辨率1200x1600,无/有后处理时帧率分别为17/7fps)
注意:车辆前方的黑色区域是投影后的盲区,因前摄像头安装不当导致。
硬件软件配置
小型车项目硬件:
- 四个USB鱼眼摄像头(支持640x480|800x600|1920x1080三种分辨率,选用640x480)
- AGX Xavier(开发也可在普通笔记本完成)
EU5项目硬件:
- 四个960x640 CSI摄像头(使用Sekonix SF3326-100-RCCB型号)
- 同款AGX Xavier
软件环境:
- Ubuntu 16.04/18.04
- Python≥3
- OpenCV≥3
- PyQt5(主要用于多线程处理)
实施步骤
1. 相机标定准备
使用项目中的run_calibrate_camera.py
脚本进行标定。标定图像存放在images/
目录:
前视 | 后视 | 左侧 | 右侧 |
---|---|---|---|
![]() | ![]() | ![]() | ![]() |
标定参数存储在yaml
目录下的对应文件中。地面标定板尺寸为6m×10m,黑白方格40cm×40cm,带圆格80cm×80cm。
2. 投影参数设置
通过地面标定板计算各相机的投影矩阵,将图像转换为鸟瞰视角。关键参数包括:
innerShiftWidth/Height
:标定板内缘与车辆的间距shiftWidth/Height
:期望扩展的视野范围totalWidth/Height
:鸟瞰图覆盖区域(本例为600+2×shiftWidth, 1000+2×shiftHeight cm)
车辆区域将分为八个部分(FL/F/FR/L/R/BL/BR等),其中FL/FR/BL/BR为相邻相机重叠区域。
3. 手动选取特征点
运行run_get_projection_maps.py
脚本:
python run_get_projection_maps.py -camera front -scale 0.7 0.8 -shift -150 -100
通过点击四个特征点计算透视变换矩阵。示例过程:
-
前视摄像头校正图像:
< -
选择特征点:
-
生成鸟瞰图:
4. 图像拼接与平滑
运行run_get_weight_matrices.py
生成拼接结果:
关键技术要点:
- 重叠区域融合:采用距离加权算法(权重公式𝑤=𝑑𝐵²/(𝑑𝐴²+𝑑𝐵²))
- 亮度均衡:通过12个系数调整BGR三通道(各相机独立)
- 色彩平衡:消除不同相机间的色差
5. 实车演示
运行run_live_demo.py
进行测试。USB摄像头直接调用cv2.VideoCapture()
,CSI摄像头需使用GStreamer管道。
注意事项
- 多线程同步:使用
MultiBufferManager
类管理线程同步 - 查找表优化:预计算映射表提升处理速度
- 矩阵压缩存储:将四个权重矩阵压缩为RGBA四通道图像
脚本说明
run_calibrate_camera.py
:内参标定param_settings.py
:投影参数设置run_get_projection_maps.py
:投影点选取run_get_weight_matrices.py
:权重矩阵计算run_live_demo.py
:实车演示
该项目虽不复杂,但涉及精细计算,完整展示了从标定到实时环视的系统开发流程。