【如何衡量相机标定结果的精度】相机标定评价函数

2024-05-30 06:12

本文主要是介绍【如何衡量相机标定结果的精度】相机标定评价函数,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

相关博客:

  1. 【鱼眼+普通相机】相机标定
  2. 【opencv】图像畸变校正

一、简介

常用的衡量相机标定结果精度的评价标准:

  1. 畸变矫正效果:标定过程中会估计畸变系数,畸变矫正的效果可以通过比较矫正前后的图像来评估。如果畸变得到有效矫正,说明标定过程较为成功。
  2. 重投影误差(Reprojection Error):这是最常用的评估相机标定精度的指标。它指的是在标定图像中检测到的特征点与通过相机参数投影得到的相应世界坐标点之间的距离。理想情况下,这个距离应该非常小。重投影误差越小,表明相机标定的精度越高。
  3. 反投影残差(Residual Error):这个指标衡量的是实际的三维点投影回二维图像平面后与观测到的二维点之间的距离。反投影残差较小,表明相机标定的精度较高。
  4. 参数估计误差:通过估计相机参数的标准误差,可以计算出参数估计的不确定性。这些标准误差可以用来计算置信区间,从而评估参数估计的准确性。

下面详细介绍一下重投影误差反投影残差

二 、重投影误差

定义:

重投影误差(Reprojection Error)是指在相机标定过程中,将三维世界坐标系中的点投影到二维图像平面上,然后与实际在图像中检测到的特征点之间的差异。这个差异通常用像素单位来衡量。

计算方法:

检测特征点:首先,在标定图像中检测到的特征点(通常是角点或棋盘格的交点)。
投影三维点:使用标定过程中估计出的相机内参(焦距、主点坐标)和畸变系数,将三维世界坐标系中的点投影到二维图像平面上。
计算误差:对于每个投影点,计算其与实际检测到的特征点之间的距离(通常是欧氏距离)。
求平均误差:对所有标定图像中的特征点,计算它们的重投影误差,然后求取平均值或中位数。

影响因素:

特征点检测的准确性:如果特征点检测不准确,会导致较大的重投影误差。
相机内参和畸变系数的估计精度:这些参数的准确估计对重投影误差有直接影响。
标定图像的数量和质量:标定图像越多,覆盖的视野越广,通常可以获得更准确的相机参数估计。
标定板的位姿:标定板在图像中的位姿应该多样化,以确保相机参数的全面估计。

优化方法:

提高特征点检测精度:使用更先进的算法或提高图像质量来提高特征点检测的准确性。
增加标定图像数量:收集更多的标定图像,特别是从不同角度和位置拍摄的图像。
优化标定算法:使用更先进的标定算法,如基于非线性优化的方法,来提高参数估计的精度。
标定板设计:设计易于特征点提取的标定板,如黑白相间的棋盘格或圆点图案。
结果解释:
误差较小:如果平均重投影误差很小(例如小于一个像素),通常认为相机标定是成功的。
误差较大:如果误差较大,可能需要重新审视标定过程,检查是否有误检测的特征点、标定图像质量是否足够高,或者标定算法是否需要调整。

代码:

# 计算标定的总重投影误差
total_reproj_error = 0
for i in range(len(object_points)):projected_imgpoints, _ = cv2.projectPoints(object_points[i], rvecs[i], tvecs[i], camera_matrix, distortion_coeffs)error_per_image = np.abs(corners[i] - projected_imgpoints.reshape(-1, 2)).reshape(-1)total_reproj_error += error_per_image.mean()average_reproj_error = total_reproj_error / len(corners)print(f"Average Reprojection Error: {average_reproj_error:.4f} pixels")

三、反投影残差

反投影残差(Residual Error)是评估相机标定精度的一个重要指标,它衡量的是三维空间中的物理点与其通过相机模型投影到二维图像平面上的点之间的差异。在相机标定的过程中,我们的目标是找到相机的内参(包括焦距、主点坐标等)和畸变系数,使得三维点的投影尽可能准确地对应到图像上的特征点。

概念:

  • 三维到二维的投影:在相机标定中,我们通常知道一些三维空间中点的世界坐标,并且这些点在图像上被观测到(通常是通过特征点检测得到的)。使用相机模型,我们可以将这些三维点投影到图像平面上。
  • 残差:反投影残差是指实际观测到的特征点位置与通过相机模型从三维坐标投影得到的位置之间的差异。

计算方法:

收集三维点的世界坐标:这些点通常位于一个标定板上,它们在三维空间中的位置是已知的。
使用相机模型进行投影:根据标定得到的相机内参和畸变系数,将三维世界坐标投影到图像平面上。
计算残差:对于每个三维点,计算其投影点与实际观测到的特征点之间的距离(通常是欧氏距离)。
求总残差或平均残差:对所有标定点,计算总残差或平均残差。

影响因素:

相机内参的准确性:包括焦距、主点坐标等,这些参数的准确性直接影响投影的准确性。
畸变系数的准确性:畸变系数用于矫正镜头畸变,如果不准确,会导致投影误差。
三维点的世界坐标的准确性:如果标定板上的点的世界坐标不准确,也会影响反投影残差。
特征点检测的准确性:图像上的特征点如果检测不准确,同样会影响残差的计算。

优化方法:

改进特征点检测算法:使用更准确的算法来检测图像上的特征点。
使用更精确的标定板:确保标定板上的三维点的世界坐标测量准确。
优化相机标定算法:采用非线性优化算法来更精确地估计相机参数。
增加标定图像的数量和多样性:使用多个角度和条件下拍摄的图像,以获得更全面的相机模型。

结果解释:

  • 残差较小:如果反投影残差较小,说明相机标定的精度较高,相机模型能够准确地将三维点投影到图像平面上。
  • 残差较大:如果残差较大,则可能需要重新审视标定过程,检查是否有误检测的特征点、标定图像质量是否足够高,或者标定算法是否需要调整。
    反投影残差是一个重要的量化指标,它帮助我们了解相机标定的准确性,并指导我们进行必要的优化。在高精度要求的应用中,如机器视觉、三维重建等,最小化反投影残差是非常关键的。

代码:

# 计算反投影残差
total_residual = 0
for i in range(len(object_points)):# 将3D点投影到2Dimg_points, _ = cv2.projectPoints(object_points[i], rvecs[i], tvecs[i], camera_matrix, distortion_coeffs)# 计算残差for j in range(len(img_points)):residual = np.linalg.norm(img_points[j] - corners[i][j].reshape(2))total_residual += residualaverage_residual = total_residual / (len(object_points) * len(corners))print(f"Total Residual: {total_residual}")
print(f"Average Residual: {average_residual}")

三、两者的区别

重投影误差(Reprojection Error)和反投影残差(Residual Error)都是衡量相机标定精度的指标,但它们的定义和计算方法有所不同。

  • 重投影误差关注的是将三维点投影到二维图像平面上后与实际观测点的偏差。
  • 反投影残差关注的是将二维图像点反投影到三维空间后与实际三维点的偏差。

重投影误差更常用于标定过程中相机参数的优化,而反投影残差则更多用于评估标定结果的准确性

这篇关于【如何衡量相机标定结果的精度】相机标定评价函数的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1015785

相关文章

如何评价Ubuntu 24.04 LTS? Ubuntu 24.04 LTS新功能亮点和重要变化

《如何评价Ubuntu24.04LTS?Ubuntu24.04LTS新功能亮点和重要变化》Ubuntu24.04LTS即将发布,带来一系列提升用户体验的显著功能,本文深入探讨了该版本的亮... Ubuntu 24.04 LTS,代号 Noble NumBAT,正式发布下载!如果你在使用 Ubuntu 23.

C++11的函数包装器std::function使用示例

《C++11的函数包装器std::function使用示例》C++11引入的std::function是最常用的函数包装器,它可以存储任何可调用对象并提供统一的调用接口,以下是关于函数包装器的详细讲解... 目录一、std::function 的基本用法1. 基本语法二、如何使用 std::function

hdu1171(母函数或多重背包)

题意:把物品分成两份,使得价值最接近 可以用背包,或者是母函数来解,母函数(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v) 其中指数为价值,每一项的数目为(该物品数+1)个 代码如下: #include<iostream>#include<algorithm>

基于UE5和ROS2的激光雷达+深度RGBD相机小车的仿真指南(五):Blender锥桶建模

前言 本系列教程旨在使用UE5配置一个具备激光雷达+深度摄像机的仿真小车,并使用通过跨平台的方式进行ROS2和UE5仿真的通讯,达到小车自主导航的目的。本教程默认有ROS2导航及其gazebo仿真相关方面基础,Nav2相关的学习教程可以参考本人的其他博客Nav2代价地图实现和原理–Nav2源码解读之CostMap2D(上)-CSDN博客往期教程: 第一期:基于UE5和ROS2的激光雷达+深度RG

C++操作符重载实例(独立函数)

C++操作符重载实例,我们把坐标值CVector的加法进行重载,计算c3=c1+c2时,也就是计算x3=x1+x2,y3=y1+y2,今天我们以独立函数的方式重载操作符+(加号),以下是C++代码: c1802.cpp源代码: D:\YcjWork\CppTour>vim c1802.cpp #include <iostream>using namespace std;/*** 以独立函数

函数式编程思想

我们经常会用到各种各样的编程思想,例如面向过程、面向对象。不过笔者在该博客简单介绍一下函数式编程思想. 如果对函数式编程思想进行概括,就是f(x) = na(x) , y=uf(x)…至于其他的编程思想,可能是y=a(x)+b(x)+c(x)…,也有可能是y=f(x)=f(x)/a + f(x)/b+f(x)/c… 面向过程的指令式编程 面向过程,简单理解就是y=a(x)+b(x)+c(x)

利用matlab bar函数绘制较为复杂的柱状图,并在图中进行适当标注

示例代码和结果如下:小疑问:如何自动选择合适的坐标位置对柱状图的数值大小进行标注?😂 clear; close all;x = 1:3;aa=[28.6321521955954 26.2453660695847 21.69102348512086.93747104431360 6.25442246899816 3.342835958564245.51365061796319 4.87

OpenCV结构分析与形状描述符(11)椭圆拟合函数fitEllipse()的使用

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C++11 算法描述 围绕一组2D点拟合一个椭圆。 该函数计算出一个椭圆,该椭圆在最小二乘意义上最好地拟合一组2D点。它返回一个内切椭圆的旋转矩形。使用了由[90]描述的第一个算法。开发者应该注意,由于数据点靠近包含的 Mat 元素的边界,返回的椭圆/旋转矩形数据

Unity3D 运动之Move函数和translate

CharacterController.Move 移动 function Move (motion : Vector3) : CollisionFlags Description描述 A more complex move function taking absolute movement deltas. 一个更加复杂的运动函数,每次都绝对运动。 Attempts to

✨机器学习笔记(二)—— 线性回归、代价函数、梯度下降

1️⃣线性回归(linear regression) f w , b ( x ) = w x + b f_{w,b}(x) = wx + b fw,b​(x)=wx+b 🎈A linear regression model predicting house prices: 如图是机器学习通过监督学习运用线性回归模型来预测房价的例子,当房屋大小为1250 f e e t 2 feet^