本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:单目视觉与双目视觉是计算机视觉中实现三维环境理解的关键技术。单目视觉通过单一摄像头结合几何、运动和特征匹配等方法推断深度,而双目视觉则利用双摄像头间的视差精确计算深度信息。本资料包含详细的原理解析与MATLAB源码,涵盖相机标定、特征提取(如SIFT/SURF)、光流估计、立体匹配与三角测量等核心算法,帮助用户深入掌握视觉系统的设计与实现。通过实际代码实践,学习者可提升在位姿估计、场景重建等方面的技术能力,为从事计算机视觉研究与开发打下坚实基础。
单目视觉,单目视觉和双目视觉的区别,matlab源码.zip

1. 单目视觉基本原理与应用场景

单目视觉的成像模型与投影几何基础

单目视觉依赖针孔相机模型,通过小孔成像将三维世界投影至二维图像平面。其核心数学表达为 $ \mathbf{p} = K[R|\mathbf{t}] \mathbf{P} $,其中 $ K $ 为内参矩阵,$ [R|\mathbf{t}] $ 描述外参,实现从世界坐标到像素坐标的映射。由于深度信息在投影过程中丢失,单目系统需借助运动视差或先验知识恢复尺度结构。

典型应用场景分析

在自动驾驶中,单目系统利用语义分割与车道线拟合实现车道保持;机器人通过单目SLAM(如ORB-SLAM)构建稀疏地图并定位;AR应用则结合PnP算法估计设备姿态。这些场景共同依赖图像序列中的时空一致性与特征匹配精度。

优势与挑战并存的技术路径

单目方案成本低、部署灵活,适用于资源受限平台。然而,绝对尺度模糊与深度敏感度不足限制了其在高精度测距场景的应用,需引入额外约束(如运动假设或多模态融合)缓解固有缺陷,为后续双目对比提供必要性支撑。

2. 双目视觉工作原理与人类双眼视觉类比

双目视觉系统通过模拟人类双眼感知空间深度的机制,利用两个分离但协同工作的摄像头从不同视角采集同一场景图像,进而基于视差信息重建三维环境。其核心优势在于能够直接、实时地获取物体的距离信息,避免了单目系统中因缺乏真实尺度而导致的“尺度模糊”问题。本章将深入剖析双目视觉的几何成像机制,揭示其背后的数学原理,并以人类生物立体视觉为参照,探讨计算机系统如何借鉴生理结构实现高效的空间感知。同时,结合实际硬件设计需求,分析相机选型、同步机制及布局参数对测量精度的关键影响,构建一个从理论到工程落地的完整认知框架。

2.1 双目视觉的几何成像机制

双目视觉的核心在于通过两个已知位置关系的相机捕捉同一场景,利用图像间像素的位移——即视差(Disparity)——来推导出目标点在三维空间中的坐标。该过程依赖于严格的几何约束和精确的相机标定,是实现高精度深度估计的基础。本节将系统性地介绍平行双相机模型下的成像原理,阐述对极几何的基本概念,建立基线与视差之间的数学关系,并最终推导出三维点云生成的核心公式。

2.1.1 平行双相机模型与对极几何约束

在理想条件下,双目系统的两个相机被配置为完全平行,光轴共面且水平对齐,这种简化模型称为 平行双相机模型 。在此模型下,左右图像中的对应点仅在水平方向上存在偏移,极大简化了立体匹配的搜索空间。

设左相机位于原点 $ O_L = (0, 0, 0) $,右相机位于 $ O_R = (b, 0, 0) $,其中 $ b $ 为两相机之间的 基线距离 (Baseline)。假设两相机具有相同的焦距 $ f $ 和成像平面高度 $ h $,某三维空间点 $ P = (X, Y, Z) $ 在左右图像上的投影分别为 $ p_L = (x_L, y_L) $ 和 $ p_R = (x_R, y_R) $。

根据小孔成像模型,有:
x_L = f \cdot \frac{X}{Z}, \quad y_L = f \cdot \frac{Y}{Z}
x_R = f \cdot \frac{X - b}{Z}, \quad y_R = f \cdot \frac{Y}{Z}

由此可得视差 $ d = x_L - x_R $ 为:
d = f \cdot \frac{X}{Z} - f \cdot \frac{X - b}{Z} = \frac{fb}{Z}
\Rightarrow Z = \frac{fb}{d}

这表明深度 $ Z $ 与视差 $ d $ 成反比,是双目测距的基本原理。

对极几何约束

在非理想或未校正的情况下,双目系统需引入 对极几何 (Epipolar Geometry)进行描述。关键元素包括:

  • 极点 (Epipoles):一个相机的光心在另一个相机图像平面上的投影。
  • 极线 (Epipolar Lines):对于左图中的一点 $ p_L $,其在右图中的对应点必位于一条特定直线上,这条线称为极线。
  • 本质矩阵 E 和基础矩阵 F :描述两视图之间射影关系的3×3矩阵,满足 $ p_R^T F p_L = 0 $。
% MATLAB 示例:计算基础矩阵并绘制极线
points1 = [100, 150; 200, 300; 400, 250]; % 左图像特征点
points2 = [95, 152; 195, 305; 390, 255]; % 右图像对应点

% 使用八点法估算基础矩阵
F = estimateFundamentalMatrix(points1, points2, 'Method', 'EightPoint');

% 显示极线
figure;
I1 = imread('left_image.png');
imshow(I1); hold on;
epiLines = lineAtInfinity(F, size(I1,2)); % 自定义函数生成极线
for i = 1:size(epiLines,1)
    x = [1, size(I1,2)];
    y = -(F(i,1)*x + F(i,3)) / F(i,2);
    plot(x, y, 'Color', 'green', 'LineWidth', 1);
end
title('Epipolar Lines in Left Image');

代码逻辑分析
- estimateFundamentalMatrix 利用匹配点对估算基础矩阵 $ F $,采用八点法确保数值稳定性。
- 参数 'Method', 'EightPoint' 指定使用标准八点算法,适用于无噪声的理想情况。
- 极线方程由 $ l = F p $ 给出,表示右图中点 $ p $ 对应的极线在左图中的表达式。
- 此流程可用于验证立体匹配结果是否符合几何一致性,提升误匹配剔除能力。

概念 数学表示 物理意义
视差 $ d $ $ d = x_L - x_R $ 同一点在左右图像中的水平位移
深度 $ Z $ $ Z = \frac{fb}{d} $ 点到相机平面的垂直距离
基线 $ b $ 相机间距 决定测距灵敏度
焦距 $ f $ 成像系统的光学参数 放大视差效应
基础矩阵 $ F $ $ p_R^T F p_L = 0 $ 描述两视图间的投影约束
graph TD
    A[三维空间点P] --> B[左相机投影pL]
    A --> C[右相机投影pR]
    B --> D[视差计算d = xL - xR]
    D --> E[深度Z = fb/d]
    C --> D
    style A fill:#f9f,stroke:#333
    style E fill:#bbf,stroke:#333

该流程图清晰展示了从三维点到深度估计的完整路径,体现了双目视觉的信息流结构。

2.1.2 基线距离与视差关系建模

基线距离 $ b $ 是决定双目系统性能的关键物理参数之一。它直接影响视差范围、最小可测深度以及深度分辨率。

视差与基线的关系

由前述公式 $ Z = \frac{fb}{d} $ 可知,在固定焦距 $ f $ 下,增大基线 $ b $ 会增强视差信号,从而提高远距离物体的深度分辨能力。然而,过大的基线也会带来以下问题:

  • 近处盲区扩大 :当物体非常靠近时,视差可能超过图像宽度,导致无法匹配。
  • 遮挡增加 :视角差异变大,部分区域在一侧图像中不可见。
  • 匹配难度上升 :非重叠视野增多,降低有效匹配点数量。

因此,基线选择需权衡应用场景的需求。

深度分辨率分析

深度分辨率 $ \Delta Z $ 表示系统能区分的最小深度变化,通常定义为:
\Delta Z = \frac{Z^2}{fb} \Delta d
其中 $ \Delta d $ 为视差测量误差(通常为1像素)。可见,$ \Delta Z $ 随 $ Z^2 $ 快速增长,说明双目系统在近距离精度高,远距离迅速下降。

例如,设 $ f = 8mm, b = 60mm, \Delta d = 1px $,则在 $ Z=1m $ 处:
\Delta Z = \frac{(1000)^2}{8 \times 60} \approx 2083\,\text{mm}
而在 $ Z=2m $ 处,$ \Delta Z \approx 8333\,\text{mm} $,误差急剧上升。

% MATLAB 计算深度分辨率随距离变化
f = 8e-3;     % 焦距 (m)
b = 60e-3;    % 基线 (m)
delta_d = 1;  % 视差误差 (pixel)
Z_range = 0.5:0.1:5; % 距离范围 (m)

delta_Z = (Z_range.^2) ./ (f * b);

figure;
plot(Z_range, delta_Z*1000, 'r-', 'LineWidth', 2);
xlabel('Distance Z (m)');
ylabel('Depth Resolution \DeltaZ (mm)');
title('Depth Resolution vs Distance for f=8mm, b=60mm');
grid on;

参数说明
- 输入变量均为国际单位制,便于物理量纲统一。
- 输出以毫米为单位更直观反映实际误差。
- 曲线呈二次增长趋势,强调远距离测距局限性。

基线长度 (mm) 最小可测距离 (m) 1m处深度分辨率 (mm) 适用场景
30 0.8 ~416 室内机器人
60 1.2 ~208 自动驾驶低速探测
120 2.0 ~104 远距离监控
200 3.5 ~62 航拍地形测绘

此表可用于指导系统设计阶段的基线选择。

2.1.3 三维点云生成的基本数学推导

一旦获得视差图,即可逐像素恢复三维坐标,形成稠密点云。设左图像中某点 $ (u, v) $ 的视差为 $ d = u - u’ $,其中 $ u’ $ 为其在右图中的匹配位置。

根据针孔模型,该点对应的三维坐标 $ (X, Y, Z) $ 可通过如下公式计算:

Z = \frac{fb}{d}, \quad X = \frac{Z \cdot (u - c_x)}{f_x}, \quad Y = \frac{Z \cdot (v - c_y)}{f_y}

其中:
- $ f_x, f_y $:归一化焦距(像素单位)
- $ c_x, c_y $:主点坐标
- $ b $:基线(米)
- $ d $:视差(像素)

该过程常在OpenCV或MATLAB中通过 reprojectImageTo3D 函数实现。

% MATLAB 实现视差图转点云
stereoParams = stereoParameters(...); % 预先标定的双目参数
disparityMap = disparity(rgb2gray(I_left), rgb2gray(I_right), ...
    'DisparityRange', [0 64], 'BlockSize', 15);

% 三维重投影
point3D = reprojectImageTo3D(disparityMap, stereoParams.DisparityScale, ...
    'DisparitySolidity', disparityMap);

% 可视化点云
figure;
pcshow(point3D);
title('3D Point Cloud from Stereo Disparity');
xlabel('X'); ylabel('Y'); zlabel('Z');

执行逻辑说明
- disparity() 函数使用半全局块匹配(SGBM)算法生成视差图,支持参数调节。
- reprojectImageTo3D 利用内参和外参完成三角化,输出每个像素对应的 $ (X,Y,Z) $。
- 返回的 point3D 是 M×N×3 的数组,可直接用于点云显示或后续处理。

flowchart LR
    A[原始图像对] --> B[图像去畸变]
    B --> C[极线校正]
    C --> D[立体匹配生成视差图]
    D --> E[视差图滤波优化]
    E --> F[三维重投影]
    F --> G[输出点云数据]

此流程图概括了从输入图像到三维重建的全过程,突出了各模块的功能衔接。

此外,点云质量受多种因素影响,如纹理丰富度、光照一致性、镜头畸变等。在低纹理区域(如白墙),匹配容易失败,导致空洞;强光反射则引起误匹配。为此,常采用引导滤波(Guided Filter)或左右一致性检查(Left-Right Consistency Check)进行后处理。

综上所述,双目视觉的几何成像机制建立在严密的数学基础上,通过对视差的有效提取与解码,实现了无需主动光源的被动式三维感知。这一机制不仅具备良好的物理可解释性,也为后续系统优化提供了明确的方向指引。

2.2 人类双眼视觉的认知机理借鉴

计算机双目视觉的设计深受人类生物视觉系统的启发。人类依靠两只眼睛接收略有差异的图像,大脑通过对这些差异的解析实现深度感知,形成所谓的“立体视觉”。这一自然机制为人工双目系统提供了生物学原型。本节将解析人类双眼的生理结构,揭示视差感知与神经融合的过程,并探讨计算机系统如何仿生实现类似功能。

2.2.1 生物立体视觉的生理结构解析

人类眼球呈球形,直径约24mm,两眼间距平均为65mm,构成天然的“双目传感器”。每只眼睛通过角膜、晶状体将外界光线聚焦至视网膜,形成倒立实像。视网膜上的感光细胞(视锥与视杆细胞)将光信号转化为电信号,经由视神经传入大脑视觉皮层。

关键结构包括:

  • 黄斑区 (Macula):中央凹(Fovea)所在区域,负责高分辨率中央视觉。
  • 视盘 (Optic Disc):视神经出口,形成生理盲点。
  • 双眼视域重叠区 :约120°水平视野重合,提供立体视觉基础。

由于两眼空间位置不同,观察同一物体时会产生不同的投影角度,这种差异即为 生理视差 。大脑利用这种微小差异判断距离,形成深度感。

研究表明,人类可检测的最小视差约为0.5弧分(1 arcmin = 1/60 degree),相当于在10米远处分辨相距2.9mm的两点。这种高灵敏度源于视皮层V1区神经元对特定方向和视差的调谐响应。

参数 人类值 机器参考
眼距(基线) 60–70 mm 50–200 mm
焦距(等效) ~17 mm 4–50 mm
分辨率 ~576 MP(全视野) 8–50 MP(典型相机)
动态范围 ~10^9:1 ~10^5:1(HDR)

尽管机器传感器在某些指标上超越人类,但在自适应性和能耗效率方面仍存在差距。

2.2.2 视差感知与大脑融合机制模拟

大脑并非简单比较两眼图像的位置差,而是经历复杂的神经处理过程。初级视觉皮层(V1)中的简单细胞和复杂细胞对边缘、方向敏感,而高级区域如V2、V3则整合多尺度信息,形成视差选择性神经元。

一个重要机制是 双眼竞争 (Binocular Rivalry)与 融合 (Fusion)。当两眼看到的内容差异过大时,大脑交替感知两者;而在适度差异下,则将其融合为单一立体图像。

计算机系统通过 立体匹配算法 模拟这一过程。常见方法包括:

  • 局部方法 :如块匹配(Block Matching, BM),计算局部窗口内的相似度(如SSD、SAD)。
  • 全局方法 :如动态规划、图割(Graph Cut),优化整体能量函数。
  • 半全局方法 :如SGBM(Semi-Global Block Matching),折中效率与精度。
% MATLAB 中使用SGM进行立体匹配
matcher = disparitySGM('DisparityRange',[0,64],...
    'HadamardTransform', true,...
    'SpeckleFilter', true);

disparityMap = matcher(rgb2gray(I_left), rgb2gray(I_right));

参数说明
- 'DisparityRange' 设定搜索范围,影响最大可测深度。
- 'HadamardTransform' 提升匹配鲁棒性。
- 'SpeckleFilter' 去除孤立噪声点。

该过程类似于大脑在多个候选匹配中寻找最优解,体现了仿生智能的思想。

2.2.3 计算机双目系统对生物机制的仿生实现

现代双目系统在多个层面模仿人类视觉:

  1. 结构仿生 :采用相近基线(60–70mm)模拟人眼间距,优化近距离感知。
  2. 处理仿生 :引入注意力机制(Attention Model)优先处理中央区域,类似黄斑聚焦。
  3. 自适应仿生 :动态调整曝光、增益,模仿瞳孔调节。

此外,深度学习模型(如PSMNet、GCNet)借鉴了视觉皮层的分层特征提取结构,使用卷积神经网络自动学习视差表示,显著提升了复杂场景下的匹配准确性。

graph BT
    H[人类视觉系统] --> H1[双眼采集]
    H --> H2[视网膜编码]
    H --> H3[大脑融合与识别]
    M[双目机器系统] --> M1[双相机采集]
    M --> M2[FPGA/ISP预处理]
    M --> M3[GPU立体匹配+AI推理]

    H1 <--> M1
    H2 <--> M2
    H3 <--> M3

该对比图显示了生物与人工系统在信息处理链路上的高度对应性。

2.3 双目视觉系统的关键组件设计

高性能双目系统不仅依赖算法,还需精心设计硬件架构。本节聚焦三大核心组件:相机选型与同步机制、图像采集与传输优化、以及硬件布局对精度的影响。

2.3.1 相机选型与同步触发机制

相机应具备:
- 高帧率(≥30fps)以支持动态场景;
- 全局快门避免运动模糊;
- 支持硬件触发同步。

常用接口包括GigE Vision、USB3 Vision、Camera Link。

% MATLAB 设置硬件同步采集
vidobj_left = videoinput('gige', 1, 'Mono8');
vidobj_right = videoinput('gige', 2, 'Mono8');

set(vidobj_left, 'TriggerType', 'Hardware');
set(vidobj_right, 'TriggerType', 'Hardware');

start([vidobj_left, vidobj_right]);

使用外部信号发生器同时触发两台相机,确保时间严格对齐。

2.3.2 图像采集卡与数据传输优化

高分辨率图像产生大量数据(如1280×720×8bit×30fps ≈ 221 Mbps/路),需高速采集卡支持DMA传输,减少CPU负担。

建议使用支持GenICam协议的采集卡,兼容性强。

2.3.3 硬件布局对测量精度的影响分析

刚性支架防止振动引起的相对位移。温度变化会导致材料膨胀,影响基线稳定性。

建议使用Invar合金或碳纤维材料,热膨胀系数低。

定期重新标定可维持长期精度。

3. 单目与双目视觉的核心区别(深度获取方式、精度、硬件需求)

在计算机视觉系统设计中,单目与双目视觉作为两类主流的三维感知技术路径,其根本差异不仅体现在硬件构成上,更深刻地反映在信息获取机制、系统性能边界以及工程部署成本等维度。理解二者之间的本质区别,是构建高效、鲁棒且可扩展视觉系统的前提。本章将从 深度信息获取机制的本质差异 系统性能指标对比分析 硬件架构与部署成本权衡 三个核心层面展开深入探讨,结合数学建模、算法流程图示、MATLAB代码片段及参数分析,揭示两种方案在实际应用中的适用边界。

3.1 深度信息获取机制的本质差异

深度估计是视觉感知任务的核心目标之一。然而,单目与双目系统在实现这一目标时所依赖的信息来源和推理逻辑存在根本性不同:单目系统依赖于 时间序列上的运动推断与结构恢复 ,而双目系统则通过 空间并行视角下的视差直接测距 完成深度重建。这种机制上的分野决定了两者在精度、稳定性与场景适应性方面的显著差异。

3.1.1 单目视觉中的结构恢复与运动推断(SfM)

单目相机仅能捕获二维图像,缺乏直接的深度线索。因此,必须借助外部动态信息——通常是摄像机自身的移动——来间接恢复三维结构。这一过程被称为“Structure from Motion”(SfM),即从图像序列中同时估计相机姿态变化和场景三维点云。

SfM 的基本假设是:同一物理点在多个视角下投影为不同的像素位置,利用这些对应关系可以反解出该点的空间坐标。其核心步骤包括特征提取、特征匹配、本质矩阵/基础矩阵估计、三角化、PnP位姿求解与Bundle Adjustment优化。

下面是一个简化的 SfM 流程图,使用 Mermaid 格式表示:

graph TD
    A[图像采集] --> B[特征检测: ORB/SIFT]
    B --> C[特征描述与匹配]
    C --> D[去除误匹配: RANSAC + Fundamental Matrix]
    D --> E[初始化两帧间相对位姿]
    E --> F[三角化获得初始3D点]
    F --> G[跟踪更多帧: PnP + Local BA]
    G --> H[全局Bundle Adjustment优化]
    H --> I[输出稠密或稀疏点云]

该流程强调了 时间连续性 的重要性:若无足够视点变化,则无法形成有效的三角测量基线,导致深度估计失效。

示例代码:基于 MATLAB 实现的简化 SfM 关键帧处理逻辑
% 输入:imageCell - 图像元胞数组;K - 内参矩阵
function [points3D, cameraPoses] = simpleSfM(imageCell, K)
    points3D = [];
    cameraPoses = [];

    % 第一帧作为参考帧
    prevImg = im2gray(imageCell{1});
    [features1, validPoints1] = extractFeatures(prevImg, 'Method', 'ORB');
    for i = 2:length(imageCell)
        currImg = im2gray(imageCell{i});
        [features2, validPoints2] = extractFeatures(currImg, 'Method', 'ORB');
        % 特征匹配
        indexPairs = matchFeatures(features1, features2);
        matchedPoints1 = validPoints1(indexPairs(:,1));
        matchedPoints2 = validPoints2(indexPairs(:,2));

        % 计算基础矩阵并剔除误匹配
        F = estimateFundamentalMatrix(matchedPoints1.Location, ...
                                     matchedPoints2.Location, 'Method', 'RANSAC');
        inlierIdx = pointInFrontOfBothCameras(matchedPoints1, matchedPoints2, K, K, F);
        inlierPts1 = matchedPoints1(inlierIdx);
        inlierPts2 = matchedPoints2(inlierIdx);

        % 恢复相对位姿 (假设已知尺度)
        [R, t, emat] = relativeCameraPose(inlierPts1, inlierPts2, K, F);

        % 三角化得到3D点
        P1 = K * [eye(3), zeros(3,1)];           % 第一帧投影矩阵
        P2 = K * [R, t];                        % 当前帧投影矩阵
        points3D_i = triangulate(inlierPts1, inlierPts2, P1, P2);

        % 累积相机位姿(累积变换)
        if isempty(cameraPoses)
            cameraPoses(1) = rigid3d(eye(3), [0;0;0]);
        end
        currentPose = rigid3d(R, t);
        cumulativePose = compose(cameraPoses(i-1), currentPose);
        cameraPoses(i) = cumulativePose;

        % 添加新点到全局点云(需去重与融合)
        points3D = [points3D; points3D_i];
        % 更新特征用于下一帧
        features1 = features2;
        validPoints1 = validPoints2;
    end
end

逻辑逐行解读与参数说明

  • im2gray :将彩色图像转为灰度图,提升特征提取效率。
  • extractFeatures(..., 'ORB') :采用 ORB 特征进行快速关键点检测与描述,适用于实时系统。
  • matchFeatures :基于描述子距离进行最近邻匹配。
  • estimateFundamentalMatrix :通过 RANSAC 抗噪估计基础矩阵 $F$,建立对极几何约束。
  • pointInFrontOfBothCameras :筛选位于两个相机前方的匹配点,排除无效三角化结果。
  • relativeCameraPose :根据匹配点和内参恢复第二帧相对于第一帧的姿态(旋转和平移)。
  • triangulate :利用线性三角法计算三维点坐标。
  • rigid3d compose :维护全局相机轨迹,记录每帧在世界坐标系下的位姿。

此代码体现了单目 SfM 的递进式构造思想—— 以运动促结构 ,但也暴露了其脆弱性:一旦特征点稀少或纹理缺失,匹配失败会导致整个链条中断。

3.1.2 双目视觉中基于视差的直接测距原理

与单目不同,双目系统通过左右两个相机同步拍摄同一场景,利用 立体视差 (disparity)实现深度的直接计算。设两相机光心间距为基线 $B$,焦距为 $f$,某点在左图中的横坐标为 $x_l$,右图为 $x_r$,则视差定义为 $\delta = x_l - x_r$,深度公式如下:

Z = \frac{B \cdot f}{\delta}

此公式表明,深度与视差成反比。视差越大,物体越近;视差趋近于零时,物体趋于无穷远。

该方法无需相机运动即可瞬时获取深度,属于 空间域测量 而非时间域推理。

双目深度计算流程表格对比
步骤 单目视觉 双目视觉
数据输入 单摄像头图像序列 左右双摄像头同步图像
深度来源 运动引起的视点变化 固定基线下的空间视差
是否需要运动
初始化难度 高(需良好初始匹配) 低(静态标定后即可工作)
深度更新频率 帧间累积更新 每帧独立计算
对纹理依赖 极高(需丰富特征) 中等(依赖局部匹配)

表格显示,双目系统在静态条件下仍可工作,适合固定安装设备如机器人导航前端、工业检测系统。

3.1.3 时间连续性假设在单目系统中的作用

单目系统的有效性高度依赖于 时间连续性假设 ,即场景静止、相机匀速运动、图像间有足够的重叠区域。一旦出现快速运动、遮挡、光照突变或动态物体干扰,特征匹配极易失败,进而引发位姿漂移甚至系统崩溃。

相比之下,双目系统因在同一时刻获取双视图,不依赖时间演化,天然具备更强的 瞬时感知能力 。这也使其更适合应用于高速移动平台(如无人机避障)、弱纹理环境(如白墙走廊)等挑战性场景。

但值得注意的是,单目系统在长期运行中可通过闭环检测与图优化(如 ORB-SLAM 中的 Loop Closure)修正累积误差,从而实现厘米级定位精度;而双目系统虽短期精度高,却受限于基线长度,在远距离测量时误差迅速放大。

3.2 系统性能指标对比分析

选择视觉方案不能仅看理论可行性,还需综合评估其在真实环境中的表现。以下从 测量精度与误差传播特性 对光照与纹理的鲁棒性 以及 实时性与计算资源消耗 三个方面进行量化比较。

3.2.1 测量精度与误差传播特性比较

精度评估应区分近场与远场。一般而言,双目系统在 0.5m–10m 范围内具有较高精度,尤其在近距离(<3m)优于单目;而在远距离(>15m),由于视差趋近于零,信噪比下降,深度误差急剧上升。

单目系统则表现出“尺度模糊”问题:只能恢复 相对深度比例 ,除非引入额外传感器(如IMU)或已知尺寸物体进行尺度约束。

深度误差模型分析

对于双目系统,深度误差可近似表示为:

\sigma_Z \approx \frac{Z^2}{Bf} \cdot \sigma_\delta

其中 $\sigma_\delta$ 为视差估计的标准差。可见,深度误差随 $Z^2$ 增长,且受基线 $B$ 和焦距 $f$ 调控。

而对于单目系统,位置误差主要来自 姿态估计误差的积分效应 。设平移误差标准差为 $\sigma_t$,旋转误差为 $\sigma_R$,经过 $n$ 帧传播后,累计误差近似呈平方根增长:

\sigma_{pos}^{cumulative} \propto \sqrt{n} \cdot (\sigma_t + L \cdot \sigma_R)

其中 $L$ 为平均运动步长。

这意味着: 单目系统存在累积漂移风险,而双目系统存在固有分辨率限制

3.2.2 对光照变化、纹理缺失场景的鲁棒性评估

场景类型 单目视觉表现 双目视觉表现 原因分析
强光照(逆光) 易过曝失真 同样受影响,但可通过HDR缓解 曝光策略影响大
弱光照(夜间) 特征难提取,跟踪失败 匹配困难,信噪比低 噪声主导
纯色墙面/玻璃 几乎无法工作 局部失效,部分区域无值 缺乏纹理支持匹配
动态物体密集 容易误匹配导致错误三角化 视差图出现伪影 背景假设被破坏

实验数据显示,在KITTI数据集中,双目系统在城市道路环境下平均深度误差约为 5%,而单目深度学习方法(如Monodepth2)可达8%-10%,传统VO方法甚至超过15%。

此外,现代双目系统常采用 主动红外纹理投射 (如Intel RealSense)来增强弱纹理区域的匹配能力,进一步提升鲁棒性。

3.2.3 实时性与计算资源消耗对比

尽管双目系统省去了复杂的运动推断过程,但其核心瓶颈在于 立体匹配算法 的计算复杂度。

常用的局部匹配方法如 BM(Block Matching)和全局优化方法如 SGBM(Semi-Global Block Matching)均需在多个视差级别上搜索最佳匹配块,计算量巨大。

典型算法性能对比表
算法 平均耗时 (QVGA) GPU加速支持 输出质量 适用平台
BM 15–30 ms 一般 嵌入式CPU
SGBM 40–80 ms 部分 工控机
GC >100 ms 最高 离线处理
Deep Stereo Net 20–50 ms (GPU) 边缘AI芯片

而单目 VO 或 SLAM 系统虽然每帧处理较快(约10–20ms),但需持续执行 Bundle Adjustment 等非线性优化,总体负载更高。

% 示例:OpenCV 接口调用 SGBM 立体匹配(MATLAB MEX 或系统命令)
stereoMatcher = cv.StereoSGBM_create(...
    'MinDisparity', 0, ...
    'NumDisparities', 16*9, ...       % 必须是16的倍数
    'BlockSize', 3, ...
    'P1', 8*3*3^2, ...                % 梯度惩罚项
    'P2', 32*3*3^2, ...               % 更强的平滑约束
    'Disp12MaxDiff', 1, ...
    'PreFilterCap', 63, ...
    'UniquenessRatio', 10, ...
    'SpeckleWindowSize', 100, ...
    'SpeckleRange', 32);

dispMap = stereoMatcher.compute(leftImage, rightImage);
depthMap = (baseline * focal_length) ./ (dispMap + 1e-6);  % 防止除零

参数说明

  • NumDisparities :最大视差范围,决定可测最短距离。
  • BlockSize :匹配窗口大小,影响边缘细节保留程度。
  • P1/P2 :控制视差平滑性的正则化参数,过大则过度平滑。
  • UniquenessRatio :确保最优匹配显著优于次优,提高准确性。

该代码展示了如何在 MATLAB 中通过调用 OpenCV 库实现高质量视差图生成,体现了双目系统在算法层的设计精细度。

3.3 硬件架构与部署成本权衡

视觉系统的最终落地离不开硬件支撑。单目与双目在集成复杂度、标定要求和嵌入式适配方面存在显著差异。

3.3.1 单相机 vs 双相机系统的集成复杂度

维度 单目系统 双目系统
相机数量 1 2
同步需求 不需要 必须硬件同步(GPIO触发)
布局空间 小,易于隐藏 至少5–12cm间距,结构受限
散热与功耗 略高(双感光元件)
防护设计 简单密封即可 需防止基线形变(温漂、震动)

双目系统最大的工程挑战在于 保持两相机相对位姿恒定 。任何机械形变都会破坏极线校正前提,导致匹配失败。因此,常采用一体化外壳、金属支架加固,并避免高温环境长期运行。

3.3.2 标定难度与长期稳定性维护需求

单目标定仅需确定内参矩阵 $K$ 和畸变系数 $(k_1,k_2,p_1,p_2)$,通常使用棋盘格图案完成,操作简单。

双目系统则需进行 联合标定 (Stereo Calibration),不仅要各自标定内参,还需精确估计外参 $[R|t]$,尤其是平移向量中的基线分量。

% MATLAB 双目标定示例
imageSize = [640, 480];
squareSize = 25; % mm
boardSize = [9, 6];

% 加载左右相机图像对
leftImages = imageDatastore('left_calib/');
rightImages = imageDatastore('right_calib/');

% 创建棋盘格标定器
calibrator = stereoCalibrationEstimator(...
    'PatternDimensions', boardSize, ...
    'SquareSize', squareSize);

% 执行联合标定
[stereoParams, ~, ~] = estimateParameters(calibrator, leftImages.Files, rightImages.Files);

% 获取结果
K1 = stereoParams.Intrinsics1.FundamentalMatrix; % 左内参
K2 = stereoParams.Intrinsics2.FundamentalMatrix; % 右内参
R = stereoParams.RotationOfCamera2;              % 外参旋转
T = stereoParams.TranslationOfCamera2;           % 外参平移(基线)

注意事项

  • 标定板需覆盖整个视场,至少采集20组以上图像。
  • 避免反光材质,防止角点检测错误。
  • 温度变化可能导致外参漂移,建议定期重新标定或使用在线自标定算法。

3.3.3 在嵌入式平台上的可行性对比

随着边缘计算发展,越来越多视觉系统部署于 Jetson Nano、Raspberry Pi 或 FPGA 上。

平台 单目SLAM可行性 双目SGBM可行性 推荐方案
Raspberry Pi 4 ✅(轻量ORB-SLAM3 CPU版) ⚠️(BM可行,SGBM卡顿) 单目+IMU
NVIDIA Jetson Nano ✅✅ ✅(启用TensorRT加速) 双目深度估计
STM32 + FPGA ❌(算力不足) ⚠️(仅支持极简BM) 专用ASIC

实践表明,在资源受限系统中, 单目轻量化VO + IMU融合 (如VIO)是更优选择;而在算力充足的平台上, 双目+深度学习后处理 可提供最稳定的三维感知。

综上所述,单目与双目视觉各有优势与局限。前者以“巧”取胜,适合低成本、小体积场景;后者以“稳”见长,适用于高精度、高可靠性需求的应用。合理选择取决于具体任务的需求平衡。

4. MATLAB在计算机视觉中的优势与工具支持

MATLAB作为工程计算和算法开发的主流平台,在计算机视觉领域展现出强大的集成能力与高效开发特性。其核心优势在于提供了从底层图像处理到高层语义理解的一站式解决方案,尤其适合快速原型设计、教学演示以及中等规模系统验证。本章将深入探讨MATLAB如何通过其丰富的工具箱体系支撑单目与双目视觉系统的构建,并重点分析关键算法在该平台上的实现路径与优化策略。

4.1 MATLAB图像处理与计算机视觉工具箱概览

MATLAB为计算机视觉任务提供了一套高度模块化且用户友好的软件生态,主要依托于两个核心工具箱: Image Processing Toolbox Computer Vision Toolbox 。这两个工具箱不仅覆盖了基础图像操作,还封装了复杂的几何变换、特征提取、立体匹配与三维重建功能,极大降低了开发者进入门槛。

4.1.1 Image Processing Toolbox功能模块详解

Image Processing Toolbox是MATLAB中最基础也是最广泛使用的图像处理组件,涵盖从读取、显示到滤波、分割的全流程操作。其典型应用场景包括去噪、对比度增强、边缘检测等预处理步骤,这些是后续高级视觉任务的前提。

该工具箱支持多种图像格式(如JPEG、PNG、TIFF)的导入导出,并能无缝处理灰度图、彩色图及多通道图像。更重要的是,它原生支持GPU加速运算(需Parallel Computing Toolbox配合),显著提升大规模图像数据处理效率。

以下是一个使用 imread imnoise medfilt2 进行图像去噪的示例代码:

% 读取图像并添加椒盐噪声
img = imread('cameraman.tif');
noisy_img = imnoise(img, 'salt & pepper', 0.05);

% 使用中值滤波去除噪声
denoised_img = medfilt2(noisy_img, [3 3]);

% 显示结果
figure;
subplot(1,3,1); imshow(img); title('原始图像');
subplot(1,3,2); imshow(noisy_img); title('含噪图像');
subplot(1,3,3); imshow(denoised_img); title('去噪后图像');
代码逻辑逐行解读与参数说明:
  • imread('cameraman.tif') :加载名为 cameraman.tif 的测试图像,返回一个二维矩阵。
  • imnoise(..., 'salt & pepper', 0.05) :向图像添加“椒盐”噪声,其中 0.05 表示噪声密度,即5%像素被随机置为0或255。
  • medfilt2(noisy_img, [3 3]) :执行3×3窗口的中值滤波,有效抑制脉冲噪声而不模糊边缘。
  • subplot imshow 用于分屏显示图像,便于直观比较处理效果。

此流程体现了MATLAB在图像预处理阶段的高度自动化与可视化能力,适用于各类视觉系统前端的数据清洗环节。

功能类别 典型函数 应用场景
图像读写 imread , imwrite 数据加载与保存
噪声添加/去除 imnoise , medfilt2 , wiener2 鲁棒性测试与去噪
形态学操作 imerode , imdilate , bwmorph 二值图像处理、轮廓提取
边缘检测 edge , canny 特征边界识别
图像增强 histeq , adapthisteq 提升低对比度区域可见性

表 1:Image Processing Toolbox常用功能对照表

上述表格总结了该工具箱的核心函数及其对应用途,展示了其在图像质量优化方面的全面支持。

graph TD
    A[图像输入] --> B{是否含噪?}
    B -- 是 --> C[应用中值滤波或维纳滤波]
    B -- 否 --> D[直方图均衡化增强]
    C --> E[形态学闭操作填充孔洞]
    D --> E
    E --> F[输出预处理图像供后续分析]

图 1:基于Image Processing Toolbox的图像预处理流程图(Mermaid格式)

该流程图清晰表达了从原始图像输入到最终可用于特征提取的干净图像之间的标准处理链路,突出了工具箱各模块间的协同关系。

4.1.2 Computer Vision Toolbox提供的高级API

相较于基础图像处理,Computer Vision Toolbox专注于更高层次的任务建模,如相机标定、特征匹配、运动估计与三维重建。其最大特点是提供了面向对象的设计范式,例如 cameraParameters stereoParameters 类,允许开发者以结构化方式管理相机内参与外参。

一个典型的特征检测与描述子提取过程如下所示:

% 创建SIFT特征检测器
detector = detectSURFFeatures;

% 读取图像并检测关键点
I = rgb2gray(imread('building.jpg'));
points = detectSURFFeatures(I);

% 提取描述子
[features, valid_points] = extractFeatures(I, points);

% 匹配两幅图像间的特征
I2 = rgb2gray(imread('building_view2.jpg'));
points2 = detectSURFFeatures(I2);
[features2, valid_points2] = extractFeatures(I2, points2);

indexPairs = matchFeatures(features, features2);

% 获取匹配点对坐标
matchedPoints1 = valid_points(indexPairs(:,1));
matchedPoints2 = valid_points2(indexPairs(:,2));

% 可视化匹配结果
figure;
showMatchedFeatures(I, I2, matchedPoints1, matchedPoints2);
title('特征匹配结果');
代码逻辑逐行解读与参数说明:
  • detectSURFFeatures :创建一个SURF特征检测器对象,可替换为 detectSIFTFeatures detectORBFeatures 以适应不同性能需求。
  • rgb2gray :将彩色图像转为灰度图,多数特征算法仅接受单通道输入。
  • extractFeatures :基于检测到的关键点提取局部描述向量(通常为64或128维)。
  • matchFeatures :采用最近邻距离比准则(NNDR)进行初步匹配,默认使用欧氏距离。
  • showMatchedFeatures :绘制跨图像的匹配连线,直观评估匹配质量。

该代码段完整实现了从特征提取到匹配的全过程,体现了Computer Vision Toolbox对复杂视觉任务的高度抽象能力。

此外,该工具箱还内置了PnP求解器( estimateWorldCameraPose )、光流计算( opticalFlowLK )、SLAM框架( monocularMapBuilder )等高级组件,使得研究人员可以在无需重写底层算法的情况下快速搭建完整系统。

4.1.3 支持的相机接口与实时视频流处理能力

MATLAB不仅擅长离线图像分析,也具备强大的实时视频采集与处理能力。通过 Image Acquisition Toolbox ,它可以连接USB摄像头、工业相机(如Point Gray、Basler)甚至IP网络摄像机,实现实时帧捕获与流式处理。

以下是一个调用本地摄像头并实时显示视频流的示例:

% 创建视频输入对象
vidobj = videoinput('winvideo', 1); % 使用第一个可用设备
set(vidobj, 'FramesPerTrigger', Inf);
set(vidobj, 'ReturnFormat', 'double');

% 开始采集
start(vidobj);

while isrunning(vidobj)
    frame = getdata(vidobj, 1); % 获取一帧
    imshow(frame);
    pause(0.03); % 控制刷新率
end

% 清理资源
stop(vidobj);
delete(vidobj);
clear vidobj;
代码逻辑逐行解读与参数说明:
  • videoinput('winvideo', 1) :初始化Windows Video采集驱动,选择第1个摄像头设备。
  • 'FramesPerTrigger', Inf :设置无限帧触发模式,持续采集。
  • 'ReturnFormat', 'double' :指定返回数据类型为双精度浮点数,便于后续数值运算。
  • getdata(vidobj, 1) :同步获取单帧图像,阻塞直到新帧到达。
  • pause(0.03) :控制循环频率约33ms/帧,模拟30fps显示节奏。

尽管现代版本MATLAB推荐使用 webcam 类简化操作(如 cam = webcam(); img = snapshot(cam); ),但上述传统方法仍适用于需要精细控制采集参数的专业场景。

结合定时器( timer 对象)或App Designer GUI界面,可进一步实现带交互控件的实时视觉系统原型,广泛应用于机器人导航、监控分析等领域。

4.2 关键算法的MATLAB实现路径

在掌握了基本工具之后,下一步是掌握核心视觉算法的具体实现方法。本节聚焦于三大关键技术:图像预处理、特征检测与匹配、以及误匹配剔除机制,展示如何利用MATLAB高效完成这些任务。

4.2.1 图像预处理技术:去噪、增强与形态学操作

高质量的输入图像直接影响后续特征提取的准确性。因此,合理的预处理流程至关重要。除了前述的去噪方法,图像增强技术如自适应直方图均衡化(CLAHE)能显著改善光照不均问题。

% 自适应直方图均衡化增强
I = imread('low_contrast_image.png');
I_enhanced = adapthisteq(I, 'ClipLimit', 0.02, 'Distribution', 'rayleigh');

% 形态学开运算去除小噪点
se = strel('disk', 2); % 定义圆形结构元素
I_clean = imopen(I_enhanced, se);

% 显示对比
figure;
subplot(1,2,1); imshow(I); title('原始图像');
subplot(1,2,2); imshow(I_clean); title('增强+去噪后图像');
代码逻辑逐行解读与参数说明:
  • adapthisteq :执行对比度受限的自适应直方图均衡化, ClipLimit=0.02 限制过度放大噪声; Distribution='rayleigh' 假设图像强度服从瑞利分布,更适合自然场景。
  • strel('disk', 2) :创建半径为2像素的圆盘形结构元素,用于形态学操作。
  • imopen :先腐蚀后膨胀,消除孤立亮点同时保留主体形状。

此类组合操作常用于车牌识别、医学影像等对细节敏感的应用中。

4.2.2 特征检测与描述子提取(SIFT/SURF/ORB)

不同特征算法适用于不同场景。SIFT具有尺度与旋转不变性,适合远距离视角变化;ORB速度快,适合嵌入式部署;SURF则介于两者之间。

% 比较三种特征检测器性能
I = rgb2gray(imread('scene.jpg'));

% SIFT
tic;
pts_sift = detectSIFTFeatures(I);
time_sift = toc;

% SURF
tic;
pts_surf = detectSURFFeatures(I);
time_surf = toc;

% ORB
tic;
pts_orb = detectORBFeatures(I, 'ScaleFactor', 1.2, 'NumLevels', 8);
time_orb = toc;

fprintf('SIFT耗时: %.4f秒\n', time_sift);
fprintf('SURF耗时: %.4f秒\n', time_surf);
fprintf('ORB耗时: %.4f秒\n', time_orb);
性能对比分析:
算法 平均检测时间(ms) 关键点数量 适用场景
SIFT ~120 高精度匹配,离线处理
SURF ~80 中高 实时性要求适中
ORB ~15 嵌入式、无人机实时SLAM

表 2:常见特征检测算法性能对比

该实验表明,ORB在速度上具有压倒性优势,而SIFT在纹理丰富区域表现更稳定。

4.2.3 特征匹配策略与误匹配剔除(RANSAC优化)

即使经过描述子匹配,仍可能存在大量误匹配。为此,必须引入几何一致性检验机制,最常用的是基于RANSAC的单应性矩阵估计。

% 使用RANSAC剔除误匹配
H = estimateGeometricTransform(matchedPoints1, matchedPoints2, 'homography', 'MaxDistance', 10);

% 获取内点(正确匹配)
inlierPoints1 = matchedPoints1(inlierIndices);
inlierPoints2 = matchedPoints2(inlierIndices);

% 可视化内点匹配
figure;
showMatchedFeatures(I, I2, inlierPoints1, inlierPoints2);
title('RANSAC剔除后的内点匹配');
参数说明:
  • 'homography' :假设场景近似平面,使用单应性变换模型。
  • 'MaxDistance' :设定重投影误差阈值(单位:像素),超过此值视为外点。
  • 返回的 inlierIndices 指示哪些匹配点符合几何约束。

该方法可将初始匹配对中的错误率从30%-50%降低至5%以下,极大提升了后续位姿估计的可靠性。

flowchart LR
    A[原始特征匹配] --> B{是否满足几何一致性?}
    B -- 否 --> C[标记为外点并剔除]
    B -- 是 --> D[保留为内点]
    C --> E[更新变换矩阵]
    D --> E
    E --> F[输出优化后的匹配集]

图 2:基于RANSAC的误匹配剔除流程图(Mermaid格式)

该流程强调迭代优化思想,确保最终匹配结果既准确又鲁棒。

4.3 光流估计与位姿估计实战编码

光流与位姿估算是动态视觉系统的核心组成部分,前者描述像素级运动,后者反映相机整体姿态变化。MATLAB为此提供了成熟的函数接口,极大简化了实现难度。

4.3.1 稠密光流与稀疏光流的MATLAB实现

稀疏光流(Lucas-Kanade)适用于关键点跟踪,而稠密光流(Farnebäck)可获得全图运动场。

% 稀疏光流:LK方法
opticFlow = opticalFlowLK('NoiseThreshold', 0.001);
I1 = im2single(rgb2gray(imread('frame1.png')));
I2 = im2single(rgb2gray(imread('frame2.png')));

flow = estimateFlow(opticFlow, I2);
points = detectMinEigenFeatures(I1);
[points_track, flow_vector] = trackPoints(flow, points);

% 可视化轨迹
figure;
imshow(I2);
hold on;
plot([points.Location(:,1), points_track(:,1)]',...
     [points.Location(:,2), points_track(:,2)]', 'g-o');
title('稀疏光流跟踪结果');
代码解析:
  • opticalFlowLK :创建Lucas-Kanade光流估计器, NoiseThreshold 控制对微小运动的敏感度。
  • estimateFlow :计算从I1到I2的光流向量场。
  • trackPoints :根据光流预测关键点的新位置。

相比之下,稠密光流可生成完整的运动矢量图:

flow_dense = opticalFlowFarneback();
flow_dense = estimateFlow(flow_dense, I2);
figure; imshow(flowToColor(flow_dense)); title('稠密光流彩色编码图');

flowToColor 将x/y方向速度映射为HSV颜色空间,便于可视化全局运动趋势。

4.3.2 PnP算法求解相机位姿的代码解析

给定3D世界点与其在图像中的2D投影,可通过Perspective-n-Point (PnP) 算法恢复相机姿态。

% 已知3D点与对应2D点
worldPoints = [0 0 0; 1 0 0; 0 1 0; 1 1 0; 0.5 0.5 1]; % 世界坐标
imagePoints = [150 200; 300 200; 150 350; 300 350; 225 275]; % 图像坐标

% 相机内参(假设已标定)
K = [600 0 320; 0 600 240; 0 0 1];

% 求解PnP
[rotationVector, translationVector] = estimateExtrinsics(imagePoints, worldPoints, K);

% 转换为旋转矩阵
R = Rodrigues(rotationVector);
t = translationVector;

fprintf('旋转矩阵:\n'); disp(R);
fprintf('平移向量:\n'); disp(t);
参数说明:
  • estimateExtrinsics :基于EPnP或UPnP算法求解外参。
  • Rodrigues :将旋转向量转换为3×3正交矩阵。
  • 输出的 R t 构成相机相对于世界坐标的位姿变换。

该方法广泛应用于AR、无人机定位等需要精确姿态反馈的场景。

4.3.3 轨迹重建与可视化方法

最后,利用连续帧的位姿估计结果,可以重建相机运动轨迹。

% 假设有N帧的平移向量序列 T = [t1, t2, ..., tn]
T_trajectory = cumsum(translations, 1); % 累积位移

figure;
plot3(T_trajectory(:,1), T_trajectory(:,2), T_trajectory(:,3), '-*');
xlabel('X'); ylabel('Y'); zlabel('Z');
title('相机运动轨迹重建');
grid on;

结合 pcshow 可同步显示三维点云,形成完整的SLAM仿真环境。

graph TB
    A[图像序列] --> B[特征提取]
    B --> C[特征匹配]
    C --> D[RANSAC剔除外点]
    D --> E[PnP求解位姿]
    E --> F[累积得到轨迹]
    F --> G[三维可视化]

图 3:视觉SLAM轨迹重建流程图(Mermaid格式)

整个流程展示了MATLAB如何将多个独立模块串联成一个完整的视觉感知系统,充分体现了其在算法集成方面的强大能力。

5. 单目与双目视觉系统完整实现流程及MATLAB源码解析

5.1 单目视觉系统构建全流程

5.1.1 相机标定与内参矩阵获取

在单目视觉系统中,相机标定是实现精确三维重建的首要步骤。标定的目标是求解相机的内参矩阵 $ K $ 和畸变系数 $ D $,其数学形式如下:

K = \begin{bmatrix}
f_x & s & c_x \
0 & f_y & c_y \
0 & 0 & 1
\end{bmatrix}, \quad
D = [k_1, k_2, p_1, p_2, k_3]

其中 $ f_x, f_y $ 为焦距(像素单位),$ c_x, c_y $ 为主点坐标,$ s $ 为像素倾斜因子(通常接近0),$ k_i $ 为径向畸变系数,$ p_i $ 为切向畸变系数。

操作步骤
1. 使用棋盘格图案拍摄至少10张不同角度的图像;
2. 调用 MATLAB 的 cameraCalibrator 应用或编程调用 estimateCameraParameters 函数;
3. 提取角点并进行非线性优化拟合。

% 示例代码:单目相机标定
imagePoints = detectCheckerboardPoints(imageFiles);  % 检测角点
squareSize = 21.5; % 棋盘格方格边长(mm)
worldPoints = generateCheckerboardPoints([9 6], squareSize);
camIntrinsics = estimateCameraParameters(imagePoints, worldPoints);

% 输出内参矩阵和畸变系数
K = camIntrinsics.IntrinsicMatrix;
D = camIntrinsics.RadialDistortion;

5.1.2 图像序列采集与关键帧选取

为了从单目图像序列中恢复结构,需采集连续视频帧,并通过特征稳定性筛选关键帧。常用策略包括基于运动增量(如位姿变化超过阈值)或图像差异度量(如Harris角点数量下降率)。

prevPose = []; keyframes = [];
for i = 1:length(frames)
    currentImg = imread(frames{i});
    grayImg = rgb2gray(currentImg);
    points = detectHarrisFeatures(grayImg);
    if isempty(prevPose) || size(points,1) < 50
        continue;
    end
    % 计算当前帧与前一帧的相对位姿(使用PnP + RANSAC)
    [R, t] = estimateMonocularPose(prevPoints, currentPoints, K, D);
    deltaTrans = norm(t - prevT);
    if deltaTrans > 0.05  % 移动超过5cm则视为新关键帧
        keyframes{end+1} = currentImg;
        poses(end+1,:) = [R(:); t];
    end
    prevPose = [R, t];
end

5.1.3 运动恢复结构(SfM)实现与三维点云生成

利用多视图几何中的三角化方法,结合 PnP 与非线性优化(Bundle Adjustment),可逐步重建稀疏点云。

% 初始化SfM管道
sfmEngine = imageviewset;
for i = 1:length(keyframes)-1
    matchedPoints = matchFeatures(extractFeatures(keyframes{i}), ...
                                  extractFeatures(keyframes{i+1}));
    ptPairs = [keypoints{i}(matchedPoints(:,1),:), ...
               keypoints{i+1}(matchedPoints(:,2),:)];
    E = estimateEssentialMatrix(ptPairs, K);
    [R, t] = relativeCameraPose(E, K, ptPairs);
    sfmEngine = addView(sfmEngine, i, rigid3d(R,t));
    sfmEngine = addConnection(sfmEngine, i, i+1, rigid3d(R,t));
end

% 三角化并优化
pointTracks = initializeStructure(sfmEngine, K);
[reconstructedPtCloud, ~] = triangulateMultiview(pointTracks, sfmEngine.Views, K);
pcshow(reconstructedPtCloud.Location);
title('单目SfM重建结果');

5.2 双目视觉系统端到端实现

5.2.1 双目相机联合标定与极线校正

双目系统的精度高度依赖于两相机之间的外参标定。MATLAB 提供 stereoCalibration 工具箱支持联合标定。

% 加载左右相机图像集
leftImages = imageDatastore('left_calib/');
rightImages = imageDatastore('right_calib/');

% 执行联合标定
[stereoParams, leftCam, rightCam] = estimateCameraParameters(...
    leftImagePoints, rightImagePoints, boardSize, squareSize);

% 极线校正:使扫描线对齐
[rectifiedLeft, rectifiedRight, transform] = rectifyStereoImages(...
    leftImg, rightImg, stereoParams);

校正后图像满足 极线约束 :同一物点在左右图中的匹配点位于同一水平线上,极大简化立体匹配。

参数 含义
Baseline 相机基线距离(mm)
FocalLength 共享焦距(像素)
DisparityRange 最大视差搜索范围
MinDisparity 最小有效视差

5.2.2 立体匹配算法(BM/SGBM)选择与参数调优

MATLAB 支持 disparityBM (块匹配)和 disparitySGM (半全局匹配)。后者更适用于边缘保留场景。

% 配置SGBM参数
sgbm = disparitySGM('DisparityRange', [0 64], ...
                    'SpeckleFilter', true, ...
                    'UniquenessThreshold', 15);

% 计算视差图
dispMap = sgbm(rectifiedLeft, rectifiedRight);
figure; imshow(dispMap, []); colorbar; title('视差图');

参数说明表

参数名 推荐值 作用
DisparityRange [0, 64] 视差搜索区间
SpeckleFilter true 去除孤立噪点
UniquenessThreshold 10–20 匹配唯一性容忍度
P1/P2 8, 32 平滑惩罚项权重

5.2.3 视差图生成与深度图转换公式实现

深度 $ Z $ 与视差 $ d $ 的关系由下式决定:

Z = \frac{f \cdot B}{d}

其中 $ f $ 为焦距(像素),$ B $ 为基线长度(米),$ d $ 为视差值(像素)。

% 转换视差图为深度图
f = stereoParams.CameraParameters1.FocalLength(1);  % fx
B = stereoParams.TranslationVectors(1,3);           % 基线(Z方向平移)

validDisp = max(dispMap, 1e-6);
depthMap = (f * B) ./ double(validDisp);

% 可视化深度图
figure; imshow(depthMap, []); colorbar; title('深度图(单位:米)');

使用 insertText 可叠加测量信息:

annotatedImg = insertText(rectifiedLeft, [50,50], ...
    sprintf('Depth at center: %.2fm', depthMap(round(end/2), round(end/2))));
imshow(annotatedImg);

5.3 MATLAB源码结构剖析与调试技巧

5.3.1 函数模块划分与主控脚本逻辑梳理

建议采用模块化设计:

/main.m
├── /calibration/
│   ├── mono_calib.m
│   └── stereo_calib.m
├── /matching/
│   ├── compute_disparity.m
│   └── refine_disparity.m
├── /reconstruction/
│   ├── sfm_pipeline.m
│   └── pointcloud_merge.m
└── /utils/
    ├── read_camera_config.m
    └── visualize_results.m

主控脚本示例:

function main()
    mode = 'stereo';  % 'mono' or 'stereo'
    if strcmp(mode, 'mono')
        K = load_intrinsics();
        pts3D = run_sfm_pipeline(imageDir, K);
    else
        stereoParams = stereo_calib(leftDir, rightDir);
        depthMap = compute_depth_map(leftFrame, rightFrame, stereoParams);
    end
    visualize_results(depthMap);
end

5.3.2 断点调试与变量监视提升开发效率

在 MATLAB 编辑器中设置断点后,可通过“Workspace”面板查看中间变量。推荐使用 dbstop if error 自动捕获异常。

dbstop in compute_disparity at 42     % 在特定行中断
whos                                % 查看变量维度
disp(size(dispMap))                  % 输出尺寸诊断

结合 tic/toc 分析耗时:

tic;
depthMap = disparitySGM(...);
fprintf('SGM耗时: %.3fs\n', toc);

5.3.3 性能瓶颈定位与向量化优化建议

避免循环嵌套,优先使用向量化操作。例如将深度计算改写为:

% 慢:逐像素计算
for i = 1:H
    for j = 1:W
        depth(i,j) = (f*B)/max(disp(i,j), eps);
    end
end

% 快:向量化
depth = (f * B) ./ max(disp, eps);

此外,启用 gpuArray 可加速密集计算:

if canUseGPU()
    dispGpu = gpuArray(dispMap);
    depthGpu = (f * B) ./ dispGpu;
    depthMap = gather(depthGpu);
end

mermaid 流程图展示整体处理链路:

graph TD
    A[原始图像] --> B{单目/双目?}
    B -->|单目| C[相机标定]
    C --> D[关键帧提取]
    D --> E[SfM三维重建]
    B -->|双目| F[联合标定]
    F --> G[极线校正]
    G --> H[立体匹配]
    H --> I[视差转深度]
    E --> J[点云可视化]
    I --> J
    J --> K[输出结果]

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:单目视觉与双目视觉是计算机视觉中实现三维环境理解的关键技术。单目视觉通过单一摄像头结合几何、运动和特征匹配等方法推断深度,而双目视觉则利用双摄像头间的视差精确计算深度信息。本资料包含详细的原理解析与MATLAB源码,涵盖相机标定、特征提取(如SIFT/SURF)、光流估计、立体匹配与三角测量等核心算法,帮助用户深入掌握视觉系统的设计与实现。通过实际代码实践,学习者可提升在位姿估计、场景重建等方面的技术能力,为从事计算机视觉研究与开发打下坚实基础。


本文还有配套的精品资源,点击获取
menu-r.4af5f7ec.gif

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐