在这里插入图片描述

开源项目链接

车辆全景环视项目解析

在这里插入图片描述

一、项目概述

本项目是一个基于 Python + OpenCV + PyQt5 实现的车辆全景环视系统(Surround View System)。该系统通过四个鱼眼摄像头采集车辆四周图像,经过畸变校正、透视投影、图像拼接等处理步骤,最终生成一幅完整的俯视鸟瞰图,为驾驶员提供360度无死角的视野。

系统特性

  • 实时处理:支持四路摄像头实时采集和拼接
  • 鱼眼校正:基于 OpenCV 鱼眼相机模型进行畸变校正
  • 自适应亮度:自动平衡四路图像的亮度差异
  • 色彩校正:白平衡处理确保色彩一致性
  • 平滑拼接:基于距离的渐变权重融合重叠区域
  • 多平台支持:支持 USB 摄像头和 CSI 摄像头(通过 GStreamer)

二、目录结构

surround-view-system-introduction-master/
├── doc/                    # 文档目录
│   ├── img/               # 文档配图
│   └── en.md              # 英文文档
├── images/                # 测试图像
│   ├── front.png          # 前视图像
│   ├── back.png           # 后视图像
│   ├── left.png           # 左视图像
│   ├── right.png          # 右视图像
│   └── car.png            # 车辆图标
├── surround_view/         # 核心模块
│   ├── __init__.py        # 模块初始化
│   ├── base_thread.py     # 线程基类
│   ├── birdview.py        # 鸟瞰图拼接
│   ├── capture_thread.py  # 图像采集线程
│   ├── fisheye_camera.py  # 鱼眼相机模型
│   ├── imagebuffer.py     # 线程安全缓冲区
│   ├── param_settings.py  # 参数配置
│   ├── process_thread.py  # 图像处理线程
│   ├── simple_gui.py      # GUI工具
│   ├── structures.py      # 数据结构
│   └── utils.py           # 工具函数
├── yaml/                  # 相机参数文件
│   ├── front.yaml         # 前视相机参数
│   ├── back.yaml          # 后视相机参数
│   ├── left.yaml          # 左视相机参数
│   └── right.yaml         # 右视相机参数
├── run_calibrate_camera.py      # 相机标定脚本
├── run_get_projection_maps.py   # 投影标定脚本
├── run_get_weight_matrices.py   # 权重计算脚本
├── run_live_demo.py             # 实时演示脚本
└── test_cameras.py              # 相机测试脚本

目录功能说明

目录 功能 重要性
surround_view/ 核心模块,包含所有类和工具函数 核心
yaml/ 存储相机内参、畸变系数、投影矩阵 必需
images/ 测试用图像和车辆图标 可选
doc/ 项目文档和分析报告 参考

三、核心功能实现

3.1 相机标定

功能:获取鱼眼相机的内参矩阵和畸变系数

技术原理

  • 使用棋盘格标定板
  • 基于 OpenCV 的 cv2.fisheye.calibrate() 实现
  • 支持普通相机和鱼眼相机两种模式

标定流程

  1. 采集多张棋盘格图像
  2. 检测角点并亚像素精化
  3. 执行标定计算
  4. 保存参数到 yaml 文件
# 标定核心代码
ret, mtx, dist, rvecs, tvecs = cv2.fisheye.calibrate(
    objpoints, imgpoints, (W, H), K, D,
    rvecs, tvecs, calibration_flags,
    (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 1e-6)
)

3.2 畸变校正

功能:校正鱼眼镜头的径向畸变

技术原理

  • 使用 OpenCV 的 cv2.fisheye.initUndistortRectifyMap() 预计算映射表
  • 实时校正使用 cv2.remap() 进行快速映射

关键参数

  • scale_xy:校正后图像的缩放比例
  • shift_xy:校正后图像的平移量

3.3 透视投影

功能:将校正后的图像投影到俯视视角

技术原理

  • 使用单应性变换(Homography)
  • 通过手动选择四个特征点计算投影矩阵
  • 使用 cv2.getPerspectiveTransform() 获取单应矩阵

投影流程

原始图像 → 畸变校正 → 透视投影 → 方向翻转 → 鸟瞰图区域

3.4 图像拼接

功能:将四路投影图像合成为完整鸟瞰图

鸟瞰图区域划分

┌───────────────────┐
│  FL  │  F  │  FR  │  ← 前视相机
├──────┼─────┼──────┤
│  L   │  C  │  R   │  ← 左/右视相机
├──────┼─────┼──────┤
│  BL  │  B  │  BR  │  ← 后视相机
└──────┴─────┴──────┘
  • 单相机区域(F、B、L、R):直接复制对应相机的中心区域
  • 融合区域(FL、FR、BL、BR):使用渐变权重融合相邻相机的重叠部分
  • 车辆区域(C):覆盖车辆图标

3.5 亮度平衡

功能:调整四路图像的亮度使其一致

算法原理

  1. 在四个重叠区域计算相邻相机的亮度比率
  2. 求解全局亮度调整系数(几何平均)
  3. 对各通道应用非线性调整

调整公式

全局亮度系数: t = (a × b × c × d)^0.25
各相机调整系数: x = t / (d/a)^0.5

非线性调整函数

def tune(x):
    if x >= 1:
        return x * np.exp((1 - x) * 0.5)
    else:
        return x * np.exp((1 - x) * 0.8)

3.6 权重计算

功能:计算重叠区域的渐变权重矩阵

算法原理

  1. 获取两幅图像的重叠区域掩码
  2. 提取各自的非重叠部分边界
  3. 对重叠区域每个像素计算到两个边界的距离
  4. 根据距离计算权重:G = dB² / (dA² + dB²)

权重特性

  • 靠近图像 A 边界的像素,A 的权重趋近于 1
  • 靠近图像 B 边界的像素,B 的权重趋近于 1
  • 中间区域平滑过渡

四、代码架构

4.1 线程架构

系统采用多线程架构实现实时处理:

采集层 (CaptureThread × 4)
    ↓
同步层 (MultiBufferManager)
    ↓
处理层 (CameraProcessingThread × 4)
    ↓
同步层 (ProjectedImageBuffer)
    ↓
拼接层 (BirdView)
    ↓
输出层 (显示/保存)
线程类型 数量 职责
CaptureThread 4 从摄像头采集图像帧
CameraProcessingThread 4 畸变校正、投影、翻转
BirdView 1 图像拼接、亮度平衡、白平衡

4.2 核心类关系

BaseThread (线程基类)
    ├── CaptureThread (采集线程)
    ├── CameraProcessingThread (处理线程)
    └── BirdView (拼接线程)

FisheyeCameraModel (相机模型)
    └── CameraProcessingThread (使用)

Buffer (缓冲区)
    ├── MultiBufferManager (管理采集缓冲区)
    └── ProjectedImageBuffer (管理投影缓冲区)

4.3 关键类职责

类名 文件 职责
FisheyeCameraModel fisheye_camera.py 相机参数管理、畸变校正、投影变换
BirdView birdview.py 图像拼接、亮度平衡、白平衡
CaptureThread capture_thread.py 摄像头采集、帧同步
CameraProcessingThread process_thread.py 单路图像预处理
MultiBufferManager imagebuffer.py 采集线程同步
ProjectedImageBuffer birdview.py 处理线程同步
Buffer imagebuffer.py 线程安全队列

五、算法详解

5.1 鱼眼相机模型

畸变模型

x' = x(1 + k1*r² + k2*r⁴ + k3*r⁶ + k4*r⁸)
y' = y(1 + k1*r² + k2*r⁴ + k3*r⁶ + k4*r⁸)

其中 r² = x² + y²k1~k4 为畸变系数。

校正步骤

  1. 预计算映射表:cv2.fisheye.initUndistortRectifyMap()
  2. 实时校正:cv2.remap()

5.2 透视投影

单应变换

[u, v, w] = H × [x, y, 1]
x' = u/w
y' = v/w

其中 H 是 3×3 的单应矩阵,通过四个对应点计算得到。

5.3 图像融合

渐变融合公式

result = imA × G + imB × (1 - G)

其中 G 是权重矩阵(0 ≤ G ≤ 1)。

权重计算步骤

# 获取重叠区域
overlap_mask = get_overlap_region_mask(imA, imB)

# 获取边界多边形
polyA = get_outmost_polygon_boundary(imA_diff)
polyB = get_outmost_polygon_boundary(imB_diff)

# 逐像素计算权重
for y, x in indices:
    distToA = cv2.pointPolygonTest(polyA, (x, y), True)
    distToB = cv2.pointPolygonTest(polyB, (x, y), True)
    G[y, x] = distToB**2 / (distToA**2 + distToB**2)

5.4 白平衡

算法原理

# 分离通道
B, G, R = cv2.split(image)

# 计算均值
m1 = np.mean(B)
m2 = np.mean(G)
m3 = np.mean(R)

# 计算校正系数
K = (m1 + m2 + m3) / 3
c1 = K / m1
c2 = K / m2
c3 = K / m3

# 调整亮度
B = adjust_luminance(B, c1)
G = adjust_luminance(G, c2)
R = adjust_luminance(R, c3)

# 合并通道
result = cv2.merge((B, G, R))

六、运行流程

6.1 离线标定流程

Step 1: 相机内参标定
└── python run_calibrate_camera.py -i 0 -grid 9x6 -fisheye
    ↓
    输出: yaml/camera_params.yaml

Step 2: 投影矩阵标定(需执行4次,对应四个相机)
└── python run_get_projection_maps.py -camera front -scale 0.7 0.8 -shift -150 -100
    ↓
    输出: yaml/front.yaml (追加投影参数)

Step 3: 权重矩阵计算
└── python run_get_weight_matrices.py
    ↓
    输出: weights.png, masks.png, result.png

6.2 实时运行流程

python run_live_demo.py
    ↓
    1. 加载相机模型 (4个)
    2. 创建采集线程 (4个)
    3. 创建处理线程 (4个)
    4. 创建拼接线程 (1个)
    5. 启动所有线程
    6. 主循环显示结果

在这里插入图片描述


七、技术亮点

7.1 线程同步机制

采用 Barrier 同步模式确保四路相机帧同步:

def sync(self, device_id):
    self.mutex.lock()
    if device_id in self.sync_devices:
        self.arrived += 1
        if self.arrived == len(self.sync_devices):
            # 最后一个到达,唤醒所有线程
            self.buffer.add(self.current_frames)
            self.wc.wakeAll()
        else:
            # 等待其他线程
            self.wc.wait(self.mutex)
        self.arrived -= 1
    self.mutex.unlock()

7.2 预计算优化

  • 畸变校正映射表:提前计算,避免实时计算开销
  • 权重矩阵:离线计算并保存,实时运行时直接加载

7.3 自适应亮度平衡

自动检测并调整四路图像的亮度差异,无需手动参数调整。


八、应用场景

  1. 车载环视系统:为驾驶员提供360度全景视野
  2. 自动驾驶:作为环境感知的视觉输入
  3. 机器人导航:为移动机器人提供周围环境的俯视图
  4. 安防监控:多个摄像头的全景拼接

九、总结

本项目实现了一个完整的车辆全景环视系统,涵盖了从相机标定到实时拼接的完整流程。核心技术包括:

  • 鱼眼畸变校正:基于 OpenCV 鱼眼相机模型
  • 透视投影变换:手动标定获取单应矩阵
  • 多线程架构:实现高效的实时处理
  • 自适应亮度平衡:自动调整图像亮度
  • 渐变权重融合:平滑拼接重叠区域

在这里插入图片描述

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐