本系列文章旨在系统性地阐述如何利用 Python 与 OpenCV 库,从零开始构建一个完整的双目立体视觉系统。

本项目github地址:https://github.com/present-cjn/stereo-vision-python.git

1. 概述

欢迎来到本系列文章的最后一篇。在过去的几篇文章中,我们已经逐一攻克了相机标定、立体匹配和三维重建这三大核心技术模块。我们拥有了独立的零件,现在可以将它们组装成一台功能完备、性能可靠的机器了。

本文将作为我们项目的最终“用户手册”和“设计复盘”。我们将详细剖析 main.py 是如何作为程序的“大脑”,通过命令行界面(CLI)来调度和编排所有模块的。同时,本文也将提供一份比 README.md 更详尽的、包含所有使用场景的完整操作指南。

✨ 主要功能

  • 相机标定:
    • 采用高鲁棒性的两步标定法,先进行单目标定,再求解双目相对位姿。
    • 自动检测棋盘格角点,并进行亚像素级优化。
    • 生成并保存包含内外参、旋转/平移矩阵和畸变系数的 stereo_params.yml 文件。
  • 立体匹配:
    • 使用经典的 SGBM (Semi-Global Block Matching) 算法计算视差图。
    • 所有SGBM算法的超参数均在 config.py 中可配置。
  • 三维重建:
    • 利用视差图和重投影矩阵 Q 将二维图像信息重建为三维点云。
    • 对生成的点云进行过滤和降采样以获得更干净的结果。
    • 支持将点云数据保存为 .ply 文件,可在其他3D软件(如 MeshLab)中使用。
  • 交互式可视化:
    • 提供了两种最终成果的可视化方式:
    1. 3D点云显示:使用 Open3D 库进行交互式三维点云可视化(可选安装)。
    2. 交互式深度图:实时显示伪彩色的深度图,当鼠标悬停在图像上时,可以显示该像素点的真实世界距离(毫米)。
    • 提供“详细模式” (--verbose),可以显示校正图像对、原始视差图等所有中间调试步骤。
  • 专业的工程实践:
    • 模块化设计: 将不同功能(标定、处理、工具、可视化)解耦到独立的模块中。
    • 命令行界面: 基于 argparse 构建,支持 calibrate 和 run 等不同子命令,并提供详细的帮助信息。
    • 自动化测试: 包含 pytest 单元测试和稳定性测试,确保代码质量和算法的健壮性。
    • 依赖管理: 使用 requirements.txt 文件管理核心依赖,并支持可选依赖(open3d)。

📂 项目结构

stereo-vision-project/  
├── 📄 main.py                       # 主程序入口,命令行界面  
├── 📄 config.py                     # 所有配置参数  
├── 📄 requirements.txt              # 项目核心依赖  
|  
├── 📁 calibration/                  # 📷 相机标定模块  
│    └── calibrator.py  
│ 
├── 📁 processing/                   # 核心处理模块  
│    ├── stereo_matcher.py          # 立体匹配  
│    └── reconstructor.py            # 三维重建  
│ 
├── 📁 utils/                        # 🛠️ 通用工具函数  
│    ├── file_utils.py               # 文件读写  
│    ├── image_utils.py              # 图像处理  
│    └── sorting_utils.py            # 自然排序  
│ 
├── 📁 visualization/                # 📊 可视化模块  
│    └── visualizer.py  
│ 
├── 📁 tests/                        # 测试代码  
│    ├── test_calibration.py  
│    └── test_calibration_stability.py  
│ 
└── 📁 data/                         # 🗃️ 数据  ├── calibration_images/         # 用于标定的棋盘格图片  └── test_images/                # 用于立体匹配的测试图片

2. 设计回顾

在我们开始深入 main.py 之前,有必要再次回顾我们的项目架构。我们没有将所有代码都写在一个文件里,而是设计了 calibration, processing, utils, visualization 等多个模块。

这种模块化设计的核心优势在于解耦——每个模块都像一个独立的专家,只负责自己的工作。

main.py 它不执行任何具体的算法,它的唯一职责就是任务调度用户交互。它通过解析用户的命令行指令,来决定应该“聘请”哪位专家(调用哪个类),并为它们提供必要的“工具”和“原材料”(传递配置和数据)。

main.py 命令行接口详解

我们使用 Python 内置的 argparse 库来构建一个专业、灵活的命令行界面。这使得我们的程序不再是一个简单的脚本,而是一个真正的工具。

全局选项:--verbose / -v

我们设计了一个对所有子命令都有效的全局选项 --verbose。这在命令行工具设计中是一个非常标准的实践。

  • 作用: 控制程序的“详细程度”。当启用此标志时,程序会显示所有中间过程的可视化结果(如角点检测图、校正图、原始视差图),并可能打印更详细的日志。
  • 实现: 我们在主解析器 parser 上定义这个参数,并在程序启动时,用它的值去设置一个全局的配置状态 config.VERBOSE_MODE。这样,任何模块都可以通过查询 config.VERBOSE_MODE 来决定自己的行为,而无需与 argparse 直接耦合。
子命令一:calibrate

此命令负责执行完整的相机标定流程。我们为它设计了极其灵活的参数处理方式,兼顾了开发者的便利性和最终用户的灵活性。

  • 核心参数:
    • --corners <宽>,<高>: 用于指定标定板的内角点数量。
    • --size <边长mm>: 用于指定标定板方格的物理尺寸。
  • “配置作为默认,参数作为覆盖”模式:
    • 对于开发者: 在 IDE 中直接运行 python main.py calibrate 时,程序会自动从 config.py 中读取 DEFAULT_CHESSBOARD_SIZEDEFAULT_SQUARE_SIZE_MM 作为参数。这使得调试过程无需任何额外配置。
    • 对于用户: 用户可以通过命令行提供 --corners--size 参数,这些参数会覆盖掉 config.py 中的默认值,使其可以使用任何规格的标定板。
子命令二:run

此命令负责执行从图像加载到最终结果可视化的完整流水线。

  • 核心参数:
    • --view-3d: 这是一个可选的布尔标志。
  • 默认行为: python main.py run 会执行所有计算,保存点云文件,并默认显示交互式2D深度图。这是核心的、最轻量的可视化功能。
  • 可选功能: 如果用户安装了 open3d 库并希望查看三维结果,可以添加 --view-3d 标志。程序会在显示2D深度图的同时,额外弹出一个可交互的3D点云窗口。
  • “渐进式增强”设计: 我们将 open3d 设计为一个可选依赖。表示即使用户没有安装这个大型库,项目的核心功能(包括2D深度图显示)也完全可以正常运行。只有在用户尝试使用 --view-3d 时,程序才会检查 open3d 是否存在,如果不存在,则会给出安装提示。

3. 完整使用手册

现在我们从克隆这个项目开始进行一次完整的演示。

3.1. 准备工作
  1. 克隆项目并进入目录:
git clone https://github.com/present-cjn/stereo-vision-python.git
cd stereo-vision-project
  1. 创建并激活虚拟环境:
python -m venv venv
source venv/bin/activate
  1. 安装依赖:
# 安装核心依赖
pip install -r requirements.txt
# (可选) 安装3D可视化依赖
pip install open3d
3.2. 执行相机标定
  • 目标: 生成 output/stereo_params.yml 文件。
  • 准备: 你需要准备好一组双目相机拍摄的棋盘格图片,并将你的标定图片已放入 data/calibration_images/,左右图像分别以 leftPic\*.jpg 和 rightPic\*.jpg 命名。如果想要使用其他自定义路径,可以修改config.py中的CALIBRATION_IMAGE_DIR
  • 命令:
# 使用项目自带的标定图片,可以直接运行(使用config.py中的默认值)
python main.py calibrate# 使用你自己的标定板参数运行
python main.py calibrate --corners 11,8 --size 12# 如果想观察每一步的角点检测效果
python main.py -v calibrate --corners 11,8 --size 12

--verbose / -v参数时可以看到如下过程图,表示找到了对应的棋盘角点

3.3. 运行主程序并查看结果
  • 目标: 计算视差图、重建三维点云,并进行可视化。
  • 准备: 确保 output/stereo_params.yml 已存在,并在 config.py 中配置好测试图片的路径。
  • 命令:
# 默认行为:显示交互式2D深度图
python main.py run# 额外显示3D点云(需要已安装open3d)
python main.py run --view-3d# 如果想显示所有中间过程,并最终显示点云,则用下述命令
python main.py -v run --view-3d

--verbose / -v参数时可以看到如下过程图

完成极线校正

完成视差图计算

完成深度图显示(鼠标放置右边的某个点即可显示当前点的深度信息)

完成点云图

3.4. 获取帮助
  • 目标: 查看所有可用的命令和参数。
  • 命令:
python main.py --help
python main.py calibrate --help
python main.py run --help
3.5. 参数配置

项目中的所有可调参数都集中在 config.py 文件中,包括:

  • 文件和目录路径。
  • 用于快速调试的默认棋盘格参数,可在运行时被命令行覆盖。
  • SGBM 算法的所有超参数。
  • 算法的终止条件 criteria。

4. 总结与展望

通过这个系列,我们不仅实现了一个功能完备的双目视觉系统,还遵循专业的软件工程实践,构建了一个模块化、可测试、易于维护和扩展的项目。

这只是一个起点。基于这个框架,你可以继续探索更多有趣的方向:

  • 实时处理: 修改 main.py 以从摄像头实时读取视频流,并进行实时深度估计。
  • 目标检测与测距: 结合一个目标检测模型(如 YOLO),在检测到物体的同时,利用我们的深度信息来测量它与相机之间的距离。
  • 算法替换: 尝试用 StereoBM 替换 StereoSGBM,或者探索更先进的基于深度学习的匹配算法,并对比它们的效果。

本系列文章的使命是为探索计算机视觉领域的开发者,提供一份详尽的实践指南。如果本项目对您有所帮助,希望在 GitHub 上为其点亮星标 (Star) 以示支持。此外,任何技术问题或功能建议,均可通过提交 Issue 或评论提问的方式进行探讨。感谢您的阅读与支持!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/914348.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/914348.shtml
英文地址,请注明出处:http://en.pswp.cn/news/914348.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android View 绘制流程 简述 (无限递归+BitMap问题)

绘制流程 在 Android 的 View 系统中&#xff0c;draw(canvas) 和 dispatchDraw(canvas) 是绘制流程中的两个关键方法&#xff1a; 1. draw(canvas) 方法的作用 draw(canvas) 是 View 类中的核心绘制方法&#xff0c;它的主要职责包括&#xff1a; 绘制背景 - 调用 drawBac…

算法学习笔记:18.拉斯维加斯算法 ——从原理到实战,涵盖 LeetCode 与考研 408 例题

在随机化算法领域&#xff0c;拉斯维加斯&#xff08;Las Vegas&#xff09;算法以其独特的设计思想占据重要地位。与蒙特卡洛&#xff08;Monte Carlo&#xff09;算法不同&#xff0c;拉斯维加斯算法总能给出正确的结果&#xff0c;但运行时间具有随机性 —— 在最坏情况下可…

26-计组-指令执行过程

一、指令周期1. 定义与组成定义&#xff1a;CPU取出并执行一条指令所需的全部时间&#xff0c;称为指令周期。子周期划分&#xff1a;取指周期&#xff08;必选&#xff09;&#xff1a;从存储器取指令到指令寄存器&#xff08;IR&#xff09;。间址周期&#xff08;可选&#…

【JMeter】数据驱动测试

文章目录创建数据文件加载数据文件根据数据文件请求接口、传递参数拓展含义&#xff1a;根据数据的数量、内容&#xff0c;自动的决定用例的数据和内容。数据驱动测试用例。步骤&#xff1a; 创建数据文件加载数据文件根据数据文件请求接口、传递参数 创建数据文件 Jmeter支…

Springboot实现一个接口加密

首先来看效果这个主要是为了防止篡改请求的。 我们这里采用的是一个AOP的拦截&#xff0c;在有需要这样的接口上添加了加密处理。 下面是一些功能防篡改HMAC-SHA256 参数签名密钥仅客户端 & 服务器持有防重放秒级时间戳 有效窗口校验默认允许 5 分钟防窃听AES/CBC/PKCS5Pa…

斯坦福 CS336 动手大语言模型 Assignment1 BPE Tokenizer TransformerLM

所有代码更新至 https://github.com/WangYuHang-cmd/CS336/tree/main/assignment1-basics 作业文件结构: CS336/assignment1-basics/ ├── tests/ # 测试文件目录 │ ├── adapters.py # 适配器测试 │ ├── conftest.py # pyt…

Spring Cloud Gateway 实战指南

关键词&#xff1a;微服务、API网关、Spring Cloud Gateway、路由转发、限流熔断 ✅ 文章摘要 随着互联网应用规模的不断扩大&#xff0c;传统的单体架构逐渐向微服务架构转型。在微服务架构中&#xff0c;API 网关作为系统的入口点&#xff0c;承担了诸如请求路由、负载均衡、…

PyTorch自动微分:从基础到实战

目录 1. 自动微分是什么&#xff1f; 1.1 计算图 1.2 requires_grad 属性 2. 标量和向量的梯度计算 2.1 标量梯度 2.2 向量梯度 3. 梯度上下文控制 3.1 禁用梯度计算 3.2 累计梯度 4. 梯度下降实战 4.1 求函数最小值 4.2 线性回归参数求解 5. 总结 在深度学习中&a…

Spring AI 项目实战(十六):Spring Boot + AI + 通义万相图像生成工具全栈项目实战(附完整源码)

系列文章 序号文章名称1Spring AI 项目实战(一):Spring AI 核心模块入门2Spring AI 项目实战(二):Spring Boot + AI + DeepSeek 深度实战(附完整源码)3Spring AI 项目实战(三):Spring Boot + AI + DeepSeek 打造智能客服系统(附完整源码)4

从零到一:企业如何组建安全团队

在这个"黑客满天飞&#xff0c;漏洞遍地跑"的时代&#xff0c;没有安全团队的企业就像裸奔的勇士——虽然很有勇气&#xff0c;但结局往往很悲惨。 &#x1f4cb; 目录 为什么要组建安全团队安全团队的核心职能团队架构设计人员配置策略技术体系建设制度流程建立实施…

业务访问控制-ACL与包过滤

业务访问控制-ACL与包过滤 ACL的定义及应用场景ACL&#xff08;Access Control List&#xff0c;访问控制列表&#xff09;是用来实现数据包识别功能的&#xff1b;ACL可以应用于诸多场景&#xff1a; 包过滤功能&#xff1a;对数据包进行放通或过滤操作。NAT&#xff08;Netwo…

穿梭时空的智慧向导:Deepoc具身智能如何赋予导览机器人“人情味”

穿梭时空的智慧向导&#xff1a;Deepoc具身智能如何赋予导览机器人“人情味”清晨&#xff0c;当第一缕阳光透过高大的彩绘玻璃窗&#xff0c;洒在博物馆光洁的地板上&#xff0c;一位特别的“馆员”已悄然“苏醒”。它没有制服&#xff0c;却有着清晰的指引&#xff1b;它无需…

PostgreSQL 查询库中所有表占用磁盘大小、表大小

SELECTn.nspname AS schema_name,c.relname AS table_name,-- 1️⃣ 总大小&#xff08;表 toast 索引&#xff09;pg_size_pretty(pg_total_relation_size(c.oid)) AS total_size,-- 2️⃣ 表不包含索引&#xff08;含 TOAST&#xff09;pg_size_pretty(pg_total_relation_s…

日记-生活随想

最近鼠鼠也是来到上海打拼&#xff08;实习&#xff09;了&#xff0c;那么秉持着来都来了的原则&#xff0c;鼠鼠也是去bw逛了逛&#xff0c;虽说没票只能在外场看看&#x1f62d;。可惜几乎没有多少我非常喜欢的ip&#xff0c;不由感慨现在的二次元圈已经变样了。虽说我知道内…

串口A和S的含义以及RT的含义

A async 异步S sync 同步RT 收发U A RT 异步U SA RT 同步/异步

spring cloud负载均衡分析之FeignBlockingLoadBalancerClient、BlockingLoadBalancerClient

本文主要分析被 FeignClient 注解的接口类请求过程中负载均衡逻辑&#xff0c;流程分析使用的依赖版本信息如下&#xff1a;<spring-boot.version>3.2.1</spring-boot.version><spring-cloud.version>2023.0.0</spring-cloud.version><com.alibaba.…

ref 和 reactive

文章目录ref 和 reactive一、差异二、能否替代的场景分析&#xff08;1&#xff09;基本类型数据&#xff08;2&#xff09;对象类型数据&#xff08;3&#xff09;数组类型数据&#xff08;4&#xff09; 需要整体替换的场景三、替代方案与兼容写法1. 用 reactive 模拟 ref2. …

BatchNorm 与 LayerNorm:原理、实现与应用对比

BatchNorm 与 LayerNorm&#xff1a;原理、实现与应用对比 Batch Normalization (批归一化) 和 Layer Normalization (层归一化) 是深度学习中两种核心的归一化技术&#xff0c;它们解决了神经网络训练中的内部协变量偏移问题&#xff0c;大幅提升了模型训练的稳定性和收敛速度…

OcsNG基于debian一键部署脚本

&#x1f914; 为什么有了GLPI还要部署OCS-NG&#xff1f; 核心问题&#xff1a;数据收集的风险 GLPI直接收集的问题&#xff1a; Agent直接向GLPI报告数据时&#xff0c;任何收集异常都会直接影响资产数据库网络问题、Agent故障可能导致重复资产、错误数据、资产丢失无法对收集…

001_Claude开发者指南介绍

Claude开发者指南介绍 目录 Claude简介Claude 4 模型开始使用核心功能支持资源 Claude简介 Claude 是由 Anthropic 构建的高性能、可信赖和智能的 AI 平台。Claude 具备出色的语言、推理、分析和编程能力&#xff0c;可以帮助您解决各种复杂任务。 想要与 Claude 聊天吗&a…