【相机标定】OpenCV 相机标定中的重投影误差与角点三维坐标计算详解
摘要:
本文将从以下几个方面展开,结合典型代码深入解析 OpenCV 中的相机标定过程,重点阐述重投影误差的计算方法与实际意义,并通过一个calcBoardCornerPositions()
函数详细讲解棋盘格角点三维坐标的构建逻辑。
在计算机视觉领域,相机标定(Camera Calibration)是获取相机内参数和畸变参数的关键步骤。而重投影误差(Reprojection Error)则是衡量标定精度的重要指标。在使用 OpenCV 进行标定时,我们经常会接触到一个名为 computeReprojectionErrors()
的函数,它用于计算重投影误差,帮助我们评估标定结果的准确性。
↓↓↓↓↓↓ 以下正文 ↓↓↓↓↓↓
一、重投影误差是什么?
在相机标定中,我们使用一个带有已知几何尺寸的标定板(如棋盘格)进行拍摄,通过提取图像中的角点并与其在世界坐标系中的真实三维位置进行比较,来拟合相机的内参(焦距、主点)与畸变参数。
重投影误差定义为:
将三维点通过估计得到的相机内参、外参投影回图像平面后,与实际检测到的二维图像点之间的距离。
重投影误差越小,说明标定模型与实际相机系统越吻合。
在 OpenCV 中,这个误差通常用像素为单位来表示,计算结果常用于衡量整个标定质量的好坏。
OpenCV 中的计算方式
computeReprojectionErrors(objectPoints, rvecs, tvecs, reprojectionErrors);
objectPoints
: 世界坐标系中的三维点数组rvecs
: 每一张标定图像的旋转向量tvecs
: 每一张标定图像的平移向量reprojectionErrors
: 输出每张图像的重投影误差
重投影误差一般多大算合理?
一般经验值如下:
- 小于 0.5 像素:标定质量非常好,适用于高精度需求。
- 0.5 ~ 1.0 像素:精度良好,适用于大部分应用。
- 1.0 ~ 2.0 像素:仍可接受,但存在优化空间。
- 大于 5 像素:标定可能存在错误或数据异常。
因此,如果你得到的误差值为 20.5 像素,就需要对标定流程和输入数据进行彻底排查。
二、重投影误差异常的原因分析
当我们遇到过大的重投影误差(比如 10 像素以上)时,很可能是以下几个方面出现了问题:
1. 棋盘格角点检测不准确
- 照片模糊、曝光不均、反光严重导致角点提取失败或偏移。
- 建议使用
drawChessboardCorners()
显示检测结果,手动验证角点匹配质量。
2. 标定板尺寸设置错误
- 如果你的标定板上一个格子的实际物理大小是 25mm,而你误填为 1mm 或 100mm,都会导致估计的相机矩阵出现异常。
3. 数据单位不统一
- 确保所有物理坐标(如角点位置)单位一致,且以米或毫米为准。
4. 输入图像质量差或数量太少
- 用于标定的图片最好在 10 张以上,覆盖不同视角与姿态。
- 图像需保证清晰、没有严重的畸变或遮挡。
5. 相机模型选择不当
- OpenCV 支持多种畸变模型,如
CV_CALIB_RATIONAL_MODEL
。错误的模型可能造成拟合能力下降。
三、异常相机矩阵的常见原因
相机矩阵的一般形式如下:
[ fx 0 cx ]
[ 0 fy cy ]
[ 0 0 1 ]
fx
,fy
: 焦距,单位为像素cx
,cy
: 图像主点(通常为图像中心)
如果你得到了一个如下的相机矩阵:
[42880.11, 0, 959.5;0, 42880.11, 539.5;0, 0, 1]
说明焦距异常大,很可能是以下问题导致的:
1. 标定板单位或格子大小设置错误
- 如果设定了极小的格子大小,比如 0.01(但实际是 10mm),那么焦距会被放大一千倍。
2. 视角变化不足
- 如果所有标定图片角度过于一致,优化过程无法正确拟合真实焦距。
3. 初始估计参数错误
- 有些标定代码会使用初始猜测值进行非线性优化。如果初始估计离实际值相差太远,会导致最终估计错误。
建议检查棋盘格实际物理尺寸,并可尝试使用 OpenCV 的 calibrateCamera()
函数中的 CALIB_USE_INTRINSIC_GUESS
标志手动输入初值。
四、棋盘格角点三维坐标构造
在相机标定时,我们需要构造真实世界中棋盘格角点的位置(objectPoints),这组点是在一个统一世界坐标系中的固定值,是整个标定过程的关键输入。
下面是一段典型的构造函数:
private void calcBoardCornerPositions(Mat corners) {final int cn = 3;float[] positions = new float[mCornersSize * cn];for (int i = 0; i < mPatternSize.height; i++) {for (int j = 0; j < mPatternSize.width * cn; j += cn) {positions[(int) (i * mPatternSize.width * cn + j + 0)] =(2 * (j / cn) + i % 2) * (float) mSquareSize;positions[(int) (i * mPatternSize.width * cn + j + 1)] =i * (float) mSquareSize;positions[(int) (i * mPatternSize.width * cn + j + 2)] = 0;}}corners.create(mCornersSize, 1, CvType.CV_32FC3);corners.put(0, 0, positions);
}
关键参数说明:
mPatternSize
: 表示棋盘格的宽度(列数)和高度(行数)。mCornersSize
: 所有角点的总数,等于rows * cols
mSquareSize
: 每个格子的边长(单位应与物理一致,比如毫米或米)positions
: 一维数组,存储所有角点的三维坐标(X, Y, Z)Mat corners
: 输出结果,一个 OpenCV 的矩阵,每一行为一个三维坐标点(CV_32FC3)
坐标构造逻辑分析
(2 * (j / cn) + i % 2) * mSquareSize
这表示 x 轴的坐标,注意 (j / cn)
得到的是列索引 col
,乘以2再加上偶数行偏移 i % 2
,可能是为了构建某种 错位网格或蜂窝形图案,而不是标准矩形棋盘格。
i * mSquareSize
表示 y 轴坐标,也就是所在行数乘以边长。
z = 0
说明所有角点都在 z=0 的平面上,即假设标定板是平的、位于 XY 平面。
五、实践建议与调试技巧
-
统一单位: 确保
mSquareSize
和 objectPoints 的单位统一,并与实际物理尺寸一致。 -
角点可视化: 使用
drawChessboardCorners()
函数确认每张图像角点是否准确。 -
图像多样性: 包括不同角度、远近、旋转的图片,有利于提高拟合精度。
-
重投影误差判断标准:
- 如果误差 > 2px,应考虑重新标定或排查数据。
-
5px 时大概率是数据异常或逻辑错误。
-
参数初始化: 可尝试为
calibrateCamera()
提供初始猜测值,防止最优化陷入局部极值。
结语
OpenCV 的相机标定流程虽然成熟,但对输入数据质量和逻辑严谨性要求较高。重投影误差是衡量标定质量的重要指标,若遇到过大数值,往往意味着标定逻辑、数据精度或单位设定存在问题。同时,正确构造棋盘格角点的三维坐标对于整个流程至关重要。
相关文章:
【相机标定】OpenCV 相机标定中的重投影误差与角点三维坐标计算详解
摘要: 本文将从以下几个方面展开,结合典型代码深入解析 OpenCV 中的相机标定过程,重点阐述重投影误差的计算方法与实际意义,并通过一个 calcBoardCornerPositions() 函数详细讲解棋盘格角点三维坐标的构建逻辑。 在计算机视觉领域…...
传统销售VS智能销售:AI如何重构商业变现逻辑
如今最会赚钱的企业早就不靠堆人力了,他们都在悄悄用AI做商业变现。当普通销售还在手动记录客户信息时,AI销售系统已经能实时追踪客户在商品页的停留时长,甚至精确到秒。 传统客服人员还在机械地复制粘贴标准话术,AI销售却已经能根…...
从设计到开发,原型标注图全流程标准化
一、原型标注图是什么? 原型标注图(Annotated Prototype)是设计原型(Prototype)的详细说明书,通过图文结合的方式,将设计稿中的视觉样式、交互逻辑、适配规则等技术细节转化为开发可理解的标准…...
Mac QT水平布局和垂直布局
首先上代码 #include "mainwindow.h" #include "ui_mainwindow.h" #include <QPushButton> #include<QVBoxLayout>//垂直布局 #include<QHBoxLayout>//水平布局头文件 MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), …...
部署Superset BI(四)连接sql server数据库
sqlserver没有出现在Superset的连接可选菜单上,这一点让我奇怪。既然没有那就按着HANA的配置方式,照猫画虎。更奇怪的是安装好还不能出现,难道superset和微软有仇? --修改配置文件 rootNocobase:/usr/superset/superset# cd docke…...
Python爬虫(22)Python爬虫进阶:Scrapy框架动态页面爬取与高效数据管道设计
目录 一、背景:Scrapy在现代爬虫中的核心价值二、Scrapy项目快速搭建1. 环境准备与项目初始化2. 项目结构解析 三、动态页面处理:集成Splash与中间件1. 配置Splash渲染服务(Docker部署)2. 修改settings.py启用中间件3. 在Spider中…...
全球实物文件粉碎服务市场洞察:合规驱动下的安全经济与绿色转型
一、引言:从纸质堆叠到数据安全的“最后一公里” 在数字化转型浪潮中,全球企业每年仍产生超过1.2万亿页纸质文件,其中包含大量机密数据、客户隐私及商业敏感信息。据QYResearch预测,2031年全球实物文件粉碎服务市场规模将达290.4…...
使用Python 打造多格式文件预览工具 — 图、PDF、Word、Excel 一站式查看
在日常办公或文件管理场景中,我们经常面临这样的问题:在一个文件夹中短时间内产生了大量不同类型的文件(如图片、PDF、Word、Excel),我们需要快速浏览和筛选这些文件的内容,却不希望一个个打开它们。有没有…...
Microsoft 365 Copilot:为Teams在线会议带来多语言语音交流新体验
随着AI技术的飞速发展,Microsoft 365 Copilot将大型语言模型(LLM)与业务数据深度融合,为用户带来了前所未有的办公体验。在Teams在线会议中,Copilot不仅能够作为智能助手提升会议效率,还能通过实时辅助同声…...
c++:双向链表容器(std::list)
目录 🧱 一、什么是 std::list? ⚙️ 二、底层结构图解 🧪 三、list 的常见操作 📦 四、完整示例代码 📌 五、特点总结对比 🛠 六、特殊函数 📚 七、list 迭代器操作 ⚠️ 八、使用场景…...
jenkins 启动报错
java.lang.UnsatisfiedLinkError: /opt/application/jdk-17.0.11/lib/libfontmanager.so: libfreetype.so.6: cannot open shared object file: No such file or directory。 解决方案: yum install freetype-devel 安装完成之后重启jenkins。...
输入顶点坐标输出立方体长宽高的神经网络
写一个神经网络,我输入立方体投影线段的三视图坐标,输出分类和长宽高 import torch from torch import nn import torch.nn.functional as F# 假设每个视图有8个顶点,每个顶点有2个坐标值,因此每种视图有16个输入特征 input_dim…...
Layui表格行点击事件监听
在 Layui 中,如果想监听表格行的点击事件,可以通过以下步骤实现: 初始化表格:首先确保你已经使用 Layui 的 table.render 方法成功渲染了你的表格。绑定行点击事件:Layui 并没有直接提供针对表格行点击的事件监听器…...
2025数维杯数学建模竞赛B题完整参考论文(共38页)(含模型、代码、数据)
2025数维杯数学建模竞赛B题完整参考论文 目录 摘要 一、问题重述 二、问题分析 三、模型假设 四、定义与符号说明 五、 模型建立与求解 5.1问题1 5.1.1问题1思路分析 5.1.2问题1模型建立 5.1.3问题1求解结果 5.2问题2 5.2.1问题2思路分析 5.2.2问题2…...
TCP套接字通信核心要点
TCP套接字通信核心要点 通信模型架构 客户端-服务端模型 CS架构:客户端发起请求,服务端响应和处理请求双向通道:建立连接后实现全双工通信 服务端搭建流程 核心步骤 创建套接字 int server socket(AF_INET, SOCK_STREAM, 0); 参数说明&am…...
Android屏蔽通话功能和短信功能
需求开发中,有个要求屏蔽电话功能和短信功能,禁止应用打电话或短信,禁止api开发出的应用打电话或短信。这个约束怎么做呢? framework/base/core/res/res/values/config.xml.....<!-- Flag indicating whether the current devi…...
STM32TIM定时中断(6)
一、TIM介绍 1、TIM简介 TIM(Timer)定时器 定时器的基本功能:定时器可以对输入的时钟进行计数,并在计数值达到设定值时触发中断。 即定时触发中断,同时也可以看出,定时器就是一个计数器,当…...
hz2新建Keyword页面
新建一个single-keywords.php即可,需要筛选项再建taxonomy-knowledge-category.php 参考:https://www.tkwlkj.com/customize-wordpress-category-pages.html WordPress中使用了ACF创建了自定义产品分类products,现在想实现自定义产品分类下的…...
STL?vector!!!
一、前言 之前我们借助手撕string加深了类和对象相关知识,今天我们将一起手撕一个vector,继续深化类和对象、动态内存管理、模板的相关知识 二、vector相关的前置知识 1、什么是vector? vector是一个STL库中提供的类模板,它是存储…...
Android SDK
Windows纯净卸载Android SDK 1.关闭所有安卓相关的程序 Android StudioEmulators 如模拟器Command prompts using SDK 如appium服务 2.移除SDK相关目录 # Delete your SDK directory F:\android_sdk\android-sdk-windows# Also check and remove if present: $env:LOCALAPP…...
老旧 LabVIEW 系统升级改造
在工业自动化领域,LabVIEW 凭借其直观的图形化编程方式和强大的数据处理能力,成为开发测试测量与控制系统的主流平台。然而,随着技术的快速迭代和业务需求的不断变化,许多早期开发的 LabVIEW 系统逐渐暴露出性能不足、功能缺失或兼…...
【IDEA_Maven】(进阶版)永久性的更改IDEA中每个项目所依赖的Maven默认配置文件及其仓库路径
【IDEA_Maven】永久性的更改IDEA中每个项目所依赖的Maven默认配置文件及其仓库路径 问题解决 问题 Maven使用在线导入,在网络不佳时,往往加载很慢。十分浪费时间,所以我们需要在maven官网找到合适版本的maven,将其压缩包下载下来…...
VSCode远程无法选择虚拟环境问题
1. 无法选择虚拟环境 1.先保证扩展安装正确, 安装python,pylance和intelliCode 2. 直接在设置(ctrl shift p)里面搜索,点击“Python:Select Interpreter”选项 3. 可能有人会出现第三步的问题,参考链接…...
七、Hadoop 历史追踪、数据安全阀与 MapReduce初体验
Hadoop 实战拾遗:作业历史追踪、数据安全阀与 MapReduce 巧算 π 一、追溯作业足迹:JobHistory Server 的配置与使用 Hadoop 集群高效运行的背后,离不开对已完成作业的细致分析。JobHistory Server (JHS) 就像是作业的“黑匣子”࿰…...
【MySQL】联合查询
个人主页:♡喜欢做梦 欢迎 👍点赞 ➕关注 ❤️收藏 💬评论 目录 一、什么是联合查询 1.概念 2.语法要求 3.示例 4.为什么要使用联合查询 内连接 1.概念 2.语法 3.步骤: 外连接 1.概念 2.分类: 左外连…...
Java 原生实现代码沙箱(OJ判题系统第1期)——设计思路、实现步骤、代码实现
设计思路: 1、保存代码文件 ✅ 目的: 将用户提交的源码以字符串形式写入磁盘,生成 .java 文件。 📌 原因: Java 是静态语言,必须先编译成 .class 文件才能运行。 需要物理文件路径来调用 javac 或使用 Java…...
课程设计。。。。
人脸考勤系统 需求分析 需求 1.实现企业日常人脸打卡需求 2.管理员要可以管理相关数据 3.可以移植到相关嵌入式设备 …..需求主要是这些,还可以让ai拓展一点 实现 1.介于可移植性这个需求,选用Qt框架,Qt框架跨平台性特比好࿰…...
gitlab相关面试题及答案
一、GitLab 基础 1. 什么是 GitLab?它与 GitHub 有什么区别? 答案: GitLab 是一个开源的 DevOps 平台,提供代码托管、CI/CD、问题跟踪等功能。与 GitHub 的主要区别: 开源与商业:GitLab 社区版开源&#x…...
『不废话』之Python 3.14 Beta版新特性
Python 3.14 的第一个Beta版已发布,有几个新特性可以提高我们的编码效率。 未来注释 在上一篇《『不废话』之Python高级特性技巧-CSDN博客》中提到3.7中新增了 “未来注释”,可以使用“from __future__ import annotations”或双引号包括的方式解决当类…...
AWS之数据分析类产品
以下是 Amazon Athena、Amazon QuickSight、AWS Lake Formation、AWS Glue、Amazon OpenSearch Service(原 Elasticsearch Service)、Amazon Kinesis Data Analytics 和 Amazon Redshift 的核心区别及典型使用场景的对比分析: 1. Amazon Athe…...
RabbitMQ消息的重复消费问题如何解决?
在RabbitMQ中,消息重复消费是一个常见问题,它通常发生在消费者处理消息时出现网络波动、节点故障或消费者自身处理逻辑异常,ACK 失败等情况,都会导致RabbitMQ 不能够正确感知消息已被成功处理,从而重新投递消息。以下是…...
5月9号.
v-for: v-bind: v-if&v-show: v-model: v-on: Ajax: Axios: async&await: Vue生命周期: Maven: Maven坐标:...
如何减少极狐GitLab 容器镜像库存储?
极狐GitLab 是 GitLab 在中国的发行版,关于中文参考文档和资料有: 极狐GitLab 中文文档极狐GitLab 中文论坛极狐GitLab 官网 减少容器镜像库存储 (BASIC ALL) 未清理的容器镜像库会随着时间的推移而变大。添加大量镜像或标签时: 获取可用标…...
怎么用idea打jar包
背景 前端使用vue开发,打包生成dist文件,需要打包成jar包 步骤 前端的dict文件放到后端的src\main\resources目录下dict文件夹改名为staticidea打开后端代码,依次点击右侧maven下的clean 、package最后会在项目的target目录下生成jar&…...
03 mysql 连接
安装 MySQL 后,我们就需要连接它。 使用命令行方式连接使用图形化工具连接一、使用命令行客户端连接 在上一节内容02 mysql 管理(Windows版)-CSDN博客 我们采用的就是这个连接方法,这种方法直接连接的是root用户,找到该命令行属性,打开可以看到里面的参数是root: 这种…...
Jenkins集成Maven
一、概述 Jenkins是一个开源的持续集成工具,用于自动化各种开发任务。Maven是一个项目管理和构建自动化工具,主要用于Java项目。通过将Jenkins和Maven集成,可以实现自动化构建、测试和部署,提高开发效率和代码质量。 二、前提条…...
Qwen智能体qwen_agent与Assistant功能初探
Qwen智能体qwen_agent与Assistant功能初探 一、Qwen智能体框架概述 Qwen(通义千问)智能体框架是阿里云推出的新一代AI智能体开发平台,其核心模块qwen_agent.agent提供了一套完整的智能体构建解决方案。该框架通过模块化设计,将L…...
Linux——MySQL基础
基础知识 连接服务器 mysql -h 127.0.0.1 -P 3306 -u root -p -h 指明登录部署了myqsl服务的主机 -P 指明访问的端口号 -u 指明用户 -p 指明登录密码(可以不填写) 什么是数据库 首先,数据库是分为服务端和客户端的: mysql是客户…...
k8s监控方案实践(二):集成Alertmanager告警与钉钉Webhook通知
k8s监控方案实践(二): 集成Alertmanager告警与钉钉Webhook通知 文章目录 k8s监控方案实践(二): 集成Alertmanager告警与钉钉Webhook通知一、Alertmanager简介1. 什么是Alertmanager?2. Promethe…...
学习threejs,使用Physijs物理引擎
👨⚕️ 主页: gis分享者 👨⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨⚕️ 收录于专栏:threejs gis工程师 文章目录 一、🍀前言1.1 ☘️Physijs 物理引擎1.1.1 ☘️…...
UG471 之 SelectIO 逻辑资源
背景 《ug471》介绍了Xilinx 7 系列 SelectIO 的输入/输出特性及逻辑资源的相关内容。 第 1 章《SelectIO Resources》介绍了输出驱动器和输入接收器的电气特性,并通过大量实例解析了各类标准接口的实现。 第 2 章《SelectIO Logic Resources》介绍了输入输出数据…...
基于HISI3519dv500的yolov8-obb车位检测
1. 数据标注 标注软件:roLabelImg 安装方式:见 https://github.com/cgvict/roLabelImg.git 操作指南: 标注后的数据格式如下: <annotation verified"no"><folder>4800</folder><filename>fr…...
Prometheus生产实战全流程详解(存储/负载/调度篇)
一、存储架构实战(TSDB深度优化) 1. 存储拓扑设计 2. 关键参数调优 4. 性能压测对照表 二、负载治理实战(百万级Series管控) 三、调度优化实战(精准采集控制) 2. 优先级调度配置 3. 自适应抓取调整 4…...
Mac电脑远程连接window系统服务器
1.下载 首先需要下载Microsoft Remote Desktop软件,下载链接如下: https://go.microsoft.com/fwlink/?linkid868963 2、软件下载成功后,可按照引导程序进行安装,成功后进入软件,可看到如下界面:...
【Qt】编译 Qt 5.15.x For Windows 基础教程 Visual Studio 2019 MSVC142 x64
【Qt】编译 Qt 5.15.x For Windows 基础教程 Visual Studio 2019 MSVC142 x64 目录 【Qt】编译 Qt 5.15.x For Windows 基础教程 Visual Studio 2019 MSVC142 x64准备工作:(必须)第一步:第二步:第三步: 建议…...
【Qt】之【Bug】点击按钮(ui->pushButton)触发非本类设置的槽函数
解决 先说解决办法,按钮在ui为默认命名ui->pushButton,后面改了下按钮名为该按钮的功能相关,就不会随意触发其他槽函数了。 没想到是这个原因。。。 可能是之前默认的objectName与旧的槽函数自动连接了 记录一下,找了好久其他的原因。 以…...
buck和boost总结
目录 1. 基本概念与原理 2. 工作模式 3. 典型应用场景 4. Buck-Boost电路:升降压结合 5. 核心区别与选择 1. 基本概念与原理 Buck电路(降压电路) 通过开关器件(如MOSFET)周期性地导通和关断,控制电感充…...
rtsp,。。。。
下面是基于 FFmpeg H.264 RTSP GStreamer 的低延时视频传输方案的详细搭建指南。此方案可将延迟控制在 <100ms,适合远程驾驶、监控等实时性要求较高的应用场景。 📦 方案架构 摄像头(OpenCV)→ FFmpeg(H.264编码…...
微信小程序地图缩放scale隐性bug
bug1 在真机环境下通过this.mapCtx.getScale获取当前地图的缩放等级带小数, 当设置scale带小数时,地图会先执行到缩放到带小数的缩放等级,然后会再次缩放取整的缩放等级(具体向上取整还是向下取整未知,两种情况都观察…...
Java中关于多态的总结
多态是面向对象编程的三大特性之一(封装、继承、多态),它允许不同类的对象对同一消息做出不同的响应。 多态的基本概念 1、定义 多态(Polymorphism)指同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果…...