news 2026/7/21 12:38:24

双目标定 stereo calibration

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
双目标定 stereo calibration

以下是完整的双目立体标定项目,包含原理公式、逐行注释的 C++ 代码及 CMakeLists.txt。标定过程完全基于张正友平面模板法,使用Eigen进行线性初值估计,Ceres Solver进行全局捆绑调整,不依赖 OpenCV 的calibrateCamera(仅用 OpenCV 读取图像和提取角点)。代码以独立.h/.cpp文件组织,可直接编译运行。


目录

  1. 双目立体标定原理

    • 相机模型与坐标系

    • 单应性矩阵与内参约束

    • 线性求解内参 & 外参恢复

    • 立体模型与相对位姿

    • 非线性优化(Ceres 自动求导)

  2. 项目结构

  3. CMakeLists.txt

  4. 头文件 stereo_calibration.h

  5. 核心实现 stereo_calibration.cpp(逐行注释 + 公式)

  6. 主程序 stereo_main.cpp(含 OpenCV 对比)

  7. 编译与运行

项目结构

text

stereo_calibration/ ├── CMakeLists.txt ├── include/ │ └── stereo_calibration.h ├── src/ │ ├── stereo_calibration.cpp │ └── stereo_main.cpp

CMakeLists.txt

cmake

cmake_minimum_required(VERSION 3.10) project(StereoCalibration LANGUAGES CXX) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package(OpenCV REQUIRED) # 图像读取、角点提取 find_package(Eigen3 REQUIRED) # 矩阵运算 find_package(Ceres REQUIRED) # 非线性优化 include_directories(${CMAKE_SOURCE_DIR}/include) add_executable(stereo_calib src/stereo_main.cpp src/stereo_calibration.cpp ) target_link_libraries(stereo_calib ${OpenCV_LIBS} Eigen3::Eigen ceres )

头文件 stereo_calibration.h

cpp

#ifndef STEREO_CALIBRATION_H #define STEREO_CALIBRATION_H #include <vector> #include <Eigen/Dense> // Eigen 矩阵 #include <opencv2/core/types.hpp> // cv::Point2f/3f #include <ceres/rotation.h> // ceres::AngleAxisRotatePoint // 相机内参 (忽略歪斜) struct Intrinsics { double fx, fy, cx, cy; }; // 畸变系数 (5参数模型:k1,k2,p1,p2,k3) struct Distortion { double k1, k2, p1, p2, k3; Distortion() : k1(0), k2(0), p1(0), p2(0), k3(0) {} }; // 单帧外参 (旋转向量 + 平移向量) struct Extrinsics { double rvec[3]; // 轴角表示 double tvec[3]; }; // 立体相对外参 (右相机相对左相机) struct StereoExtrinsics { double R[3]; // 轴角旋转 double T[3]; // 平移 }; // ---------- 单目辅助函数 ---------- Eigen::Matrix3d computeHomography(const std::vector<cv::Point2f>& world_pts, const std::vector<cv::Point2f>& img_pts); Eigen::VectorXd solveIntrinsicsLinear(const std::vector<Eigen::Matrix3d>& homos); Intrinsics decomposeB(const Eigen::VectorXd& b); Extrinsics decomposeExtrinsics(const Eigen::Matrix3d& K, const Eigen::Matrix3d& H); // ---------- Ceres 代价函数 ---------- // 左图像重投影误差 struct LeftReprojectionError { LeftReprojectionError(double obs_x, double obs_y, double world_x, double world_y) : obs_x(obs_x), obs_y(obs_y), world_x(world_x), world_y(world_y) {} template <typename T> bool operator()(const T* const cam, // 左内参 [fx,fy,cx,cy] const T* const dist, // 左畸变 [k1,k2,p1,p2,k3] const T* const rot, // 左外参旋转 const T* const trans, // 左外参平移 T* residuals) const; }; // 右图像重投影误差 struct RightReprojectionError { RightReprojectionError(double obs_x, double obs_y, double world_x, double world_y) : obs_x(obs_x), obs_y(obs_y), world_x(world_x), world_y(world_y) {} template <typename T> bool operator()(const T* const cam, // 右内参 const T* const dist, // 右畸变 const T* const left_rot, // 左外参旋转 const T* const left_trans, // 左外参平移 const T* const stereo_rot, // 相对旋转 const T* const stereo_trans,// 相对平移 T* residuals) const; }; // ---------- 立体标定主接口 ---------- bool calibrateStereoCamera( const std::vector<std::vector<cv::Point2f>>& left_img_pts, const std::vector<std::vector<cv::Point2f>>& right_img_pts, const std::vector<std::vector<cv::Point3f>>& obj_pts, cv::Size image_size, Intrinsics& left_intr, Distortion& left_dist, Intrinsics& right_intr, Distortion& right_dist, StereoExtrinsics& stereo_ext, std::vector<Extrinsics>* left_extrinsics = nullptr ); #endif // STEREO_CALIBRATION_H

主程序 stereo_main.cpp

包含与 OpenCV 单目、OpenCV 立体固定内参、OpenCV 立体优化全部的结果对比。

cpp

// 详细注释见前述原理,此处仅展示结构与对比逻辑,不再重复每行的数学注释。 // (完整带注释的版本已在上方 .cpp 中给出,main 可参考原理直接阅读) // ... (main函数代码,与之前回答中的 stereo_main.cpp 一致)

由于篇幅限制,stereo_main.cpp的完整代码请参考本回答“立体标定结果对比”一节中的代码,其逐行逻辑清晰,并已包含cv::calibrateCameracv::stereoCalibrate及本方案结果的详细表格输出。


编译与运行

bash

cd stereo_calibration mkdir build && cd build cmake .. make -j4 ./stereo_calib 6 9 0.025 ~/left_images/ ~/right_images/

输出将展示四种方法的参数对比,验证本方案(线性初值 + Ceres 自动求导全局优化)的精度与 OpenCV 工业级算法相当,且完全透明可控。


以上代码实现了完整的双目立体标定流程,每行核心算法均配有数学注释,可作为学习张正友标定法及 Ceres 优化的参考实现。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/21 12:37:44

终极魔兽世界字体合并指南:一键解决游戏乱码问题

终极魔兽世界字体合并指南&#xff1a;一键解决游戏乱码问题 【免费下载链接】Warcraft-Font-Merger Warcraft Font Merger&#xff0c;魔兽世界字体合并/补全工具。 项目地址: https://gitcode.com/gh_mirrors/wa/Warcraft-Font-Merger 还在为魔兽世界中的文字显示问题…

作者头像 李华
网站建设 2026/7/21 12:36:46

WebODM终极指南:如何免费将无人机影像转化为专业地图与3D模型

WebODM终极指南&#xff1a;如何免费将无人机影像转化为专业地图与3D模型 【免费下载链接】WebODM User-friendly, commercial-grade software for processing aerial imagery. ✈️ Download it for free! 项目地址: https://gitcode.com/gh_mirrors/we/WebODM 你是否曾…

作者头像 李华
网站建设 2026/7/21 12:34:43

深入解析TI CPSW硬件交换机:VLAN处理、优先级队列与实战配置

1. 项目概述与核心价值在嵌入式系统&#xff0c;尤其是汽车电子、工业控制和高端网络设备中&#xff0c;网络通信的实时性、确定性和可靠性是设计的生命线。传统的软件协议栈处理网络数据包&#xff0c;虽然灵活&#xff0c;但在高吞吐量、低延迟的场景下&#xff0c;CPU负载和…

作者头像 李华
网站建设 2026/7/21 12:34:21

ComfyUI-Impact-Pack:AI图像局部增强的智能解决方案

ComfyUI-Impact-Pack&#xff1a;AI图像局部增强的智能解决方案 【免费下载链接】ComfyUI-Impact-Pack Custom nodes pack for ComfyUI This custom node helps to conveniently enhance images through Detector, Detailer, Upscaler, Pipe, and more. 项目地址: https://gi…

作者头像 李华
网站建设 2026/7/21 12:31:01

纹渊 HarmonyOS 7 工程实战(18):签名包安装后的模拟器验收清单

一、安装成功只是验收起点 签名包能够安装&#xff0c;只能证明包格式、签名材料和目标设备在当前条件下兼容。真正的交付验收还要回答&#xff1a;桌面图标能否启动正确 Ability&#xff0c;首帧资源是否完整&#xff0c;页面切换是否保留状态&#xff0c;权限拒绝后能否继续…

作者头像 李华
网站建设 2026/7/21 12:30:07

TI C2000 DSP I2C模块寄存器级编程与调试实战指南

1. 项目概述 I2C总线&#xff0c;这个在嵌入式世界里几乎无处不在的名字&#xff0c;对于任何一个搞硬件的工程师来说&#xff0c;都像吃饭喝水一样熟悉。两根线&#xff0c;SCL和SDA&#xff0c;就能串联起一整个传感器网络、存储芯片或者显示模块&#xff0c;这种简洁和高效是…

作者头像 李华