# 摄像头测距方案
***Copyright © Quectel Wireless Solutions Co., Ltd. 2026. All rights reserved.***
---
该应用是一个基于 **Quectel Pi H1** 智能主控板,通过双目摄像头采集画面,在预览界面点击目标区域,测量摄像头到该物体的真实世界距离的项目。
该项目通过调用双目摄像头同时采集左右目画面,利用双目视差原理计算目标距离,并提供了摄像头标定、参数调节等辅助功能,可作为双目测距、立体视觉及机器人视觉导航类应用的参考示例。
```{image} images/image_NG2fbd8PCoN7PHxaOrhcepZHnkh.webp
:width: 800px
:height: 531px
```
# 开发资源汇总
## 开发配件清单
| **配件名称** | **数量** | **规格参数** |
| --- | --- | --- |
| Quectel Pi H1智能主控板 | 1块 | Quectel Pi H1智能生态开发板 |
| USB双目摄像头 | 1个 | 推荐分辨率:2560×720(左右各1280×720);输出格式:YUYV/MJPG |
| USB-C电源线充电器 | 1个 | 27W USB Type-C接口充电器1.2米线长中规电源PD电源适用于树莓派5代 |
| USB-C DP显示线/HDMI线 | 1根 | 规格:DP 1.4;线长:1m;接口:USB-C(公头)- USB-C(公头)
规格:HDMI 2.0;线长:1m;接口:HDMI-A(公头)-HDMI-D(公头) |
| CPU散热风扇(可选) | 1个 | 树莓派5代官方原装散热器带导热贴 |
| 显示屏 | 1个 | 24英寸HDMI显示器 |
| 棋盘格标定板(可选) | 1个 | 规格:9×6内角点(可用手机屏幕显示) |
## 配件实物参考
### Quectel套件
```{image} images/image_WlXOb789Eozty5xYhs3cGLl6nfb.webp
:width: 800px
:height: 451px
```
### 双目摄像头
```{image} images/image_KLU5bmSkDouCSfxBYSBcARtCnNT.webp
:width: 800px
:height: 468px
```
### 棋盘标定板
```{image} images/image_AsANb91y3oDfFcx51lzcwD8xnpd.webp
:width: 1830px
:height: 1330px
```
# 快速上手
## 开发准备
**Quectel Pi H1** 智能主控板出厂默认搭载 **Debian 13** 系统镜像,因此无需再次烧录镜像,仅需按照如下步骤操作即可。
## 硬件连接
### 显示连接
将HDMI线一端接入智能主控板的HDMI接口,另一端接入显示器的HDMI接口。
```{image} images/image_RSKubLE3NoIYOUxWGElc0AhenZe.webp
:width: 800px
:height: 480px
```
### 输入设备连接
将USB键盘、鼠标接入智能主控板的两个USB-A接口上,若用无线输入设备,将接收器插入USB口即可。
```{image} images/image_DfUjbWqaboDNk2xYjzhc1JSdnb3.webp
:width: 800px
:height: 468px
```
### 双目摄像头连接
将USB双目摄像头接入智能主控板的USB-A接口。
```{image} images/image_FU8fb3xwko9rE8xPd8Rcu5VUnCu.webp
:width: 800px
:height: 800px
```
### 网线连接
将网线一端接入智能主控板的千兆网口,另一端接入路由器的网口(确保路由器已联网)。
```{image} images/image_BmRHboOqeotgTrxuwgecUAEcnAf.webp
:width: 800px
:height: 501px
```
### 电源连接
将USB-A电源线的USB-A端接入电源适配器,USB-C端接入智能主控板的电源口(通常标注 **POWER IN**)。
```{image} images/image_KPsZbvoAwo12chxhnLOcfPu0nog.webp
:width: 800px
:height: 549px
```
## 项目实现
### 安装前置
确认有网络连接后,打开终端输入命令:
```plaintext
sudo apt update && sudo apt install -y v4l-utils python3-pip
```
上述命令将更新软件源并安装项目运行所需的一些库,具体包括:
- **v4l-utils**:提供 *v4l2-ctl* 等摄像头工具,用于读取和设置摄像头参数;
- **python3-pip**:Python包管理器,用于安装项目依赖。
### 获取代码
[下载代码]()
代码解压到设备
### 安装Python依赖
```plaintext
pip install -r requirements.txt
```
依赖包说明:
- **PySide6**:Qt6的Python绑定,用于构建图形用户界面;
- **opencv-python**:OpenCV图像处理库,用于摄像头采集、图像处理和立体视觉计算;
- **numpy**:数值计算库,用于矩阵运算和标定参数处理。
### 采集标定图像
运行标定图像采集工具:
```plaintext
python3 tools/capture_calib_images.py
```
程序会自动检测双目摄像头并显示预览画面,按照提示操作:
1. 将棋盘格标定板放置在摄像头前方不同位置和角度
2. 按 *s* 键保存当前图像对(建议采集15-20对)
3. 按 *q* 键退出采集程序
### 生成标定参数
采集完成后,运行标定参数生成工具:
```plaintext
python3 tools/generate_calib_params.py
```
程序会自动读取标定图像并计算双目标定参数,生成 *tools/stereo_calib_params.npz* 文件。
### 运行测距应用
完成标定后,运行主程序:
```plaintext
cd src
python3 main.py
```
程序启动后将显示图形界面,提供以下功能:
```{image} images/image_XxEwbeVgCopsT7x3cGDcrlaxnag.webp
:width: 1416px
:height: 939px
```
#### 功能按钮说明
| **按钮** | **功能说明** |
| --- | --- |
| Left Camera Preview | 左摄像头单独预览,观察画面 |
| Right Camera Preview | 右摄像头单独预览,观察画面 |
| Take Left/Right Picture | 双目拍照,检查左右画面是否存在偏移,有偏移说明双目摄像头工作正常 |
| Start Ranging Mode | 进入测距模式,点击预览画面即可测量目标距离 |
#### 日志显示区域
右侧上方区域可输出应用运行过程中的日志信息
```{image} images/image_VLWhbZNbSo3PaIxXPyPc197DnIc.webp
:width: 1416px
:height: 939px
```
#### 摄像头参数调节
程序右侧提供摄像头参数调节面板,可调节以下参数(也可根据具体摄像头可调节参数设置范围):
| **参数** | **说明** | **范围** |
| --- | --- | --- |
| Brightness | 亮度 | -64~64 |
| Contrast | 对比度 | 0~95 |
| Saturation | 饱和度 | 0~100 |
| Hue | 色调 | -2000~2000 |
| Gamma | 伽马值 | 100~300 |
| Sharpness | 锐度 | 1~7 |
| Backlight Comp | 背光补偿 | 0 / 1 |
| Exposure Time | 曝光时间 | 3~2047 |
| WB Temp | 白平衡色温 | 2800~6500 |
### 进行测距
1. 点击 **"Start Ranging Mode"** 进入测距模式
2. 在预览画面上点击目标位置
3. 等待距离计算结果显示在顶部提示栏
# 应用演示
camera_distance_video
# 摄像头测距注意事项及常见问题解决方案
## 标定图像采集注意事项
### 图像质量
**要求:**
- **清晰度保证**:确保棋盘格在左右两个摄像头中完全可见,避免运动模糊
- **光照条件**:避免强光直射和严重阴影,保证均匀光照
- **避免反光**:如果使用手机屏幕显示棋盘格,注意避免屏幕反光导致角点检测失败
**采集策略:**
- **不同距离**:在摄像头前0.3m-2m范围内变化距离
- **不同角度**:左右倾斜±30°,上下倾斜±20°,旋转±15°
- **不同位置**:棋盘格应覆盖画面的左上、右上、左下、右下、中心等不同区域
- **数量建议**:至少15对有效图像,建议20对以上以提高标定精度
**注意事项:**
- **内角点数量**:*CHESSBOARD_SIZE* 表示内角点数量,不是方格数量。例如9×6的内角点对应10×7的方格
- **物理尺寸准确性**:*SQUARE_SIZE* 必须与实际方格边长一致,直接影响基线距离和测距精度
- **打印建议**:
- 打印纸质棋盘格时,确保平整无皱褶
- 使用手机屏幕显示时,注意屏幕尺寸测量准确
- 推荐方格边长:8-12mm
**提高精度的方法:**
- **增加标定图像数量**(建议20对以上)
- **确保图像覆盖更多角度和位置**
- **提高图像清晰度,避免模糊**
- **检查棋盘格物理尺寸设置是否正确**
**验证要点:**
- **基线距离**:*baseline* 应与实际双目摄像头物理间距接近(通常40-120mm)
- **焦距一致性**:左右相机焦距应相近,差异过大说明标定有问题
- **畸变系数**:*dist_l* 和 *dist_r* 数值应在合理范围内(通常绝对值<1)
## 双目测距过程注意事项
### 测距原理与公式
```python
# 测距公式:Z = (f × B) / d# 其中:# - f: 焦距(像素)# - B: 基线距离(米)# - d: 视差(像素)
distance = (f * self._baseline) / disparity
```
**影响测距精度的关键因素:**
- **视差计算准确性**:受立体匹配算法和图像质量影响
- **标定参数准确性**:基线距离和焦距参数
- **目标点特征**:纹理丰富度影响视差计算
### SGBM立体匹配参数调优
```python
stereo = cv2.StereoSGBM_create(
minDisparity=0, # 最小视差
numDisparities=16*12, # 视差搜索范围(必须是16的倍数)
blockSize=11, # 匹配块大小(奇数,3-21)
P1=8*3*11*11, # 视差平滑惩罚项1
P2=32*3*11*11, # 视差平滑惩罚项2
disp12MaxDiff=1, # 左右一致性检查最大差异
uniquenessRatio=10, # 唯一性比率
speckleWindowSize=100, # 散斑过滤窗口大小
speckleRange=32, # 散斑过滤范围
mode=cv2.STEREO_SGBM_MODE_HH # 高精度模式)
```
**参数调优建议:**
| **参数** | **调优原则** | **影响** |
| --- | --- | --- |
| numDisparities | 根据最近测距距离调整,值越大计算越慢 | 影响最近测距距离 |
| blockSize | 纹理少时增大,纹理丰富时减小 | 影响匹配精度和速度 |
| P1/P2 | P2应大于P1,通常P2=4×P1 | 影响视差图平滑度 |
| uniquenessRatio | 值越大匹配越严格 | 减少误匹配 |
| speckleWindowSize | 去除视差图噪点 | 值越大去噪效果越强 |
### 测距精度影响因素
#### 有效测距范围
```python
# 测距范围受视差搜索范围限制
max_disparity = numDisparities # 192 (16*12)
min_distance = (f * baseline) / max_disparity
```
**示例计算:**
- 焦距f = 695像素
- 基线B = 0.0735米
- 最大视差 = 192
- 最近测距距离 = (695 × 0.0735) / 192 ≈ 0.27米
#### 视差有效性过滤
```python
# 代码中的视差过滤逻辑for dy in range(-kernel//2, kernel//2 + 1):for dx in range(-kernel//2, kernel//2 + 1):
d = disparity_map[y, x]if d > 0.5: # 过滤弱视差噪声
disparity += d
valid_count += 1
```
**注意事项:**
- 视差值过小(<0.5)通常表示无效匹配
- 采用5×5邻域平均减少噪声影响
- 有效点数过少时应提示用户重新点击
#### 距离合理性检查
```python
# 对计算结果进行合理性验证
z_3d = point_3d[2]if 0.01 < z_3d < 100.0:
distance = z_3d
else:# Z不合理时用公式计算
distance = (f * self._baseline) / disparity
```
**测距误差来源:**
- **标定误差**:基线距离和焦距参数不准确
- **视差误差**:立体匹配算法精度限制
- **图像质量**:光照、模糊、纹理不足
- **距离因素**:距离越远,视差越小,相对误差越大
---
## 常见问题及解决方案
### 标定相关问题
#### 角点检测失败率高
**现象:**
```plaintext
Warning: Skip 5th pair - chessboard not detected in left image
Valid image pairs for calibration: 8 (need ≥10)
```
**解决方案:**
- **改善光照条件,避免阴影和反光**
- **确保棋盘格完全在画面内**
- **增加图像对比度**
- **减小棋盘格尺寸或增大拍摄距离**
- **使用更清晰的棋盘格图像源**
#### 基线距离异常
**现象:**
```plaintext
Baseline Length: 0.1234 meters (应该约为0.06米)
```
**解决方案:**
- **重新测量方格实际物理尺寸**
- **检查*SQUARE_SIZE*****参数设置**
- **确保棋盘格平面平整**
- **重新进行标定**
### 测距相关问题
#### 测距结果为0或无效
**现象:**
```plaintext
Error: Ranging failed - No valid disparity points
```
**原因分析:**
- **点击区域纹理不足或重复纹理**
- **点击区域过远或过近**
- **图像质量差(模糊、光照不足)**
- **未加载标定参数**
**解决方案:**
```python
# 检查标定参数是否加载if not self._is_calibrated:
LogManager.append_log("Warning: No calibration loaded!")
```
- **确保已加载标定参数文件**
- **点击纹理丰富的区域**
- **改善光照条件**
- **调整SGBM参数增大*numDisparities***
#### 测距精度低、误差大
**现象:**
实际距离1米,测量结果0.8米或1.2米
**解决方案:**
- **检查标定质量**:重投影误差应<1.0
- **优化SGBM参数**:根据测距范围调整 *numDisparities* 和 *blockSize*
- **改善图像质量**:
```python
# 增强对比度
clahe = cv2.createCLAHE(clipLimit=6.0, tileGridSize=(8, 8))
```
#### 视差图质量差
**现象:**
视差图充满噪点,无法识别物体轮廓
**解决方案:**
- **调整预处理参数**:
```python
# 增强对比度
clahe = cv2.createCLAHE(clipLimit=6.0, tileGridSize=(8, 8))# 增强降噪
gray_left = cv2.GaussianBlur(gray_left, (5, 5), 0)
gray_left = cv2.medianBlur(gray_left, 5)
```
- **调整SGBM参数**:
```python
# 增强匹配严格性
uniquenessRatio=15
speckleWindowSize=150
```
- **检查标定参数**:重新标定以获得更好的校正效果
# 技术支持与贡献
如在使用过程中遇到问题,欢迎在 [移远官方论坛]() 提交技术咨询,我们的技术支持团队将及时为您解答。
项目开源地址:[https://github.com/Quectel-Pi/demo-camera-distance-measurement]()
欢迎提交Issue反馈问题或Pull Request贡献代码改进!