一文了解PnP算法,python opencv中的cv2.solvePnP()的使用,以及使用cv2.sovlePnP()方法标定相机和2D激光雷达

简介: 一文了解PnP算法,python opencv中的cv2.solvePnP()的使用,以及使用cv2.sovlePnP()方法标定相机和2D激光雷达

1 pnp算法概念和原理介绍

1.1 pnp算法的概念

下面几种说法都是对pnp算法要做的事情的描述,大家自己体会一下

1、PnPPerspective-n-Point)是求解 3D 到 2D 点对运动的方法。它描述了当我们知道n 个 3D 空间点以及它们的投影位置时,如何估计相机所在的位姿。——《视觉SLAM十四讲》(参考

2、通俗的讲,PnP问题就是在已知世界坐标系N个空间点的真实坐标以及这些空间点图像上的投影,如何计算相机所在的位姿。罗嗦一句:已知量是空间点的真实坐标和图像坐标,未知量(求解量)是相机的位姿。

3、PnP是用来求解3D-2D点对运动的方法参考

4、PnP问题就是指通过世界中的N个特征点图像成像中的N个像点,计算出其投影关系,从而获得相机或物体位姿的问题(参考

1.2 pnp算法的概念总结

下面我在来简单总结一下我个人的理解(参考):
image.png

使用Perspective-n-Point (PnP)算法需要知道的已知量和需要求解的未知量

1.2.1 PnP需要知道的已知量

1、需要知道n个世界坐标系下参考点的3D坐标系:$\left{c_1, c_2, c_3, ..., c_n\right}$

2、同时知道这个n个3D坐标对应相机图像坐标系上的2D投影点:$\left{u_1, u_2, u_3, ..., u_n\right}$

注意:

  • 世界坐标系下的3D点和相机坐标系下投影的2D点是一一对应的
  • 相机图像坐标系,并不是相机坐标系相机像素坐标系,注意区分

下图是四大坐标系:

image.png

3、已知相机摄像头的内参(需要自己提前标注好),相机的摄像头内参包括两部分;

  • 相机的内参矩阵
  • 相机畸变系数

内参矩阵:

$$ \text { camera matrix }=\left[\begin{array}{ccc} f_{x} & 0 & c_{x} \\ 0 & f_{y} & c_{y} \\ 0 & 0 & 1 \end{array}\right] $$

焦距$(f_x, f_y)$和光学中心$(c_x, c_y)$

畸变系数:

  • $k_1、k_2、k_3$:是径向畸变
  • $p_1、p_2$:是切向畸变

1.2.2 PnP需要求的未知量

世界坐标系摄像机坐标系之间的位姿变换 :$\left{R|t\right}$

  • R:是旋转矩阵,可以理解为绕x、y、z三个坐标轴方向的旋转
  • t:是平移,可以理解为沿x、y、z三个方向上的平移

所以从一个坐标系变换到另外一个坐标系位姿变换的自由度就是6,三个方向上的旋转和三个方向上的平移。(参考

1.3 PnP算法的用处

从上面可以知道PnP就是计算出两个坐标系之间的位姿变换的:$\left{R|t\right}$

因此PnP用途也很多:

  • 相机位姿跟踪
  • 物体位姿跟踪
  • AR/VR、
  • 机器人操作
  • SLAM中位姿初值求解
  • 相机标定,相机和激光雷达联合标定等

2 PnP的常见解法

PnP的常用解法也有很多:DLT,P3P,EPnP,UPnP

2.1 PnP解法之DLT

2.2 PnP解法之P3P

上面的文章中还介绍了很多其他的解法

2.3 PnP解法之EPnP

PnP问题是研究如何从3D-2D匹配对中求解摄像头位姿,EPnP算法是一种非迭代的PnP算法

3 opencv中solvePn()函数的介绍与使用

3.1 opencv中solvePnP函数的定义

1、在opencv中的slovePnP函数的定义
image.png

3.2 solvePnP()中参数含义:

3.2.1 solvePnP()中的参数

1、下面是solvePnP()函数参数含义解释(参考):

image.png

  • objectPoints:特征点的世界坐标,坐标值需为float型,不能为double型,可以为mat类型,也可以直接输入vector

  • imagePoints:特征点在图像中的像素坐标,可以输入mat类型,也可以直接输入vector,注意输入点的顺序要与前面的特征点的世界坐标一一对应

  • cameraMatrix相机内参矩阵

  • distCoeffs:相机的畸变参数【Mat_(5, 1)】

  • rvec:输出的旋转向量

  • tvec:输出的平移向量

  • useExtrinsicGuess: 用于SOLVEPNP迭代的参数。如果为true(1),函数使用提供的rvectvec值分别作为旋转平移向量的初始近似,并进一步优化它们。默认值为False

  • flags:PnP的计算方法

3.2.2 sovlePnP()中flags参数对应的PnP计算方法

flags取值对应的是PnP的计算方法,flags的参数选择(参考):

enum {
   
    SOLVEPNP_ITERATIVE = 0,
       SOLVEPNP_EPNP      = 1, //!< EPnP: Efficient Perspective-n-Point Camera Pose Estimation @cite lepetit2009epnp
       SOLVEPNP_P3P       = 2, //!< Complete Solution Classification for the Perspective-Three-Point Problem 
       SOLVEPNP_DLS       = 3, //!< A Direct Least-Squares (DLS) Method for PnP  @cite hesch2011direct
       SOLVEPNP_UPNP      = 4, //!< Exhaustive Linearization for Robust Camera Pose and Focal Length Estimation 
       SOLVEPNP_AP3P      = 5, //!< An Efficient Algebraic Solution to the Perspective-Three-Point Problem 
       SOLVEPNP_MAX_COUNT      //!< Used for count
};

1、cv2.SOLVEPNP_ITERATIVE=0

SOLVEPNP_ITERATIVE迭代方法是基于Levenberg-Marquardt优化。 在这种情况下,函数会找到一个使重新投影误差最小的位姿(pose),该位姿是观察到的投影imagePoints与使用projectPoints将objectPoints投影的点之间的平方距离的总和(参考)。

Levenberg-Marquardt法(LM法)是一种非线性优化方法。LM算法用于解决非线性最小二乘问题,多用于曲线拟合等场合

2、cv2.SOLVEPNP_EPNP=1

3、cv2.SOLVEPNP_P3P=2

4、cv2.SOLVEPNP_DLS=3

5、cv2.SOLVEPNP_UPNP=4

6、cv2.SOLVEPNP_AP3P=5

3.3 如何获取世界坐标和图像坐标

3.4 如何标定相机的内参(内参矩阵和畸变系数)

3.5 solvePnP()的实际使用实例

参考https://blog.csdn.net/lyhbkz/article/details/90246356
参考https://blog.csdn.net/shenxiaolu1984/article/details/50165635

3.5.1 使用solvePnP()标定相机和2D lidar激光雷达

camera_2d_lidar_calibration

cv2.solvePnP(objp, imgp, K, D, flags=cv2.SOLVEPNP_ITERATIVE)使用LM优化迭代算法介绍

  • flags=cv2.SOLVEPNP_ITERATIVE

3、epnp相关源码:


image.png

重投影误差公式:

$$reprojection\_error =\frac {1}{n} \sum_{i}^{n} \sqrt{(u-ue)^2+(v-ve)^2}$$

其中:
$$n = number\_of\_correspondences$$

目录
相关文章
|
2天前
|
机器学习/深度学习 数据采集 算法
数据稀缺条件下的时间序列微分:符号回归(Symbolic Regression)方法介绍与Python示例
有多种方法可以处理时间序列数据中的噪声。本文将介绍一种在我们的研究项目中表现良好的方法,特别适用于时间序列概况中数据点较少的情况。
14 1
数据稀缺条件下的时间序列微分:符号回归(Symbolic Regression)方法介绍与Python示例
|
3天前
|
消息中间件 关系型数据库 数据库
Python实时监测数据库表数据变化的方法
在实现时,需要考虑到应用的实时性需求、数据库性能影响以及网络延迟等因素,选择最适合的方法。每种方法都有其适用场景和限制,理解这些方法的原理和应用,将帮助开发者在实际项目中做出最合适的技术选择。
35 17
|
3天前
|
XML 数据格式 Python
Python技巧:将HTML实体代码转换为文本的方法
在选择方法时,考虑到实际的应用场景和需求是很重要的。通常,使用标准库的 `html`模块就足以满足大多数基本需求。对于复杂的HTML文档处理,则可能需要 `BeautifulSoup`。而在特殊场合,或者为了最大限度的控制和定制化,可以考虑正则表达式。
21 12
|
1天前
|
Python
全网最适合入门的面向对象编程教程:Python函数方法与接口-函数与方法的区别和lamda匿名函数
【9月更文挑战第15天】在 Python 中,函数与方法有所区别:函数是独立的代码块,可通过函数名直接调用,不依赖特定类或对象;方法则是与类或对象关联的函数,通常在类内部定义并通过对象调用。Lambda 函数是一种简洁的匿名函数定义方式,常用于简单的操作或作为其他函数的参数。根据需求,可选择使用函数、方法或 lambda 函数来实现代码逻辑。
|
9天前
|
Python
Python中几种lambda排序方法
【9月更文挑战第7天】在Python中,`lambda`表达式常用于配合排序函数,实现灵活的数据排序。对于基本列表,可以直接使用`sorted()`进行升序或降序排序;处理复杂对象如字典列表时,通过`lambda`指定键值进行排序;同样地,`lambda`也适用于根据元组的不同位置元素来进行排序。
|
1天前
|
数据处理 开发者 Python
探索Python中的列表推导式在Python编程中,列表推导式是一种简洁而高效的方法,用于从现有的列表创建新列表。本文将深入探讨列表推导式的用法、优势以及一些实际应用示例。
列表推导式是Python提供的一种强大工具,它允许开发者以更简洁的语法快速生成列表。通过结合循环和条件语句,列表推导式能够简化代码结构,提高开发效率。本文详细介绍了列表推导式的基本用法,并通过实例展示了其在数据处理、转换和过滤中的广泛应用。
8 0
|
18天前
|
机器学习/深度学习 人工智能 监控
利用Python和OpenCV实现实时人脸识别系统
【8月更文挑战第31天】本文将引导您了解如何使用Python结合OpenCV库构建一个简易的实时人脸识别系统。通过分步讲解和示例代码,我们将探索如何从摄像头捕获视频流、进行人脸检测以及识别特定个体。本教程旨在为初学者提供一条明晰的学习路径,帮助他们快速入门并实践人脸识别技术。
|
13天前
|
算法 BI Serverless
基于鱼群算法的散热片形状优化matlab仿真
本研究利用浴盆曲线模拟空隙外形,并通过鱼群算法(FSA)优化浴盆曲线参数,以获得最佳孔隙度值及对应的R值。FSA通过模拟鱼群的聚群、避障和觅食行为,实现高效全局搜索。具体步骤包括初始化鱼群、计算适应度值、更新位置及判断终止条件。最终确定散热片的最佳形状参数。仿真结果显示该方法能显著提高优化效率。相关代码使用MATLAB 2022a实现。
|
13天前
|
算法 数据可视化
基于SSA奇异谱分析算法的时间序列趋势线提取matlab仿真
奇异谱分析(SSA)是一种基于奇异值分解(SVD)和轨迹矩阵的非线性、非参数时间序列分析方法,适用于提取趋势、周期性和噪声成分。本项目使用MATLAB 2022a版本实现从强干扰序列中提取趋势线,并通过可视化展示了原时间序列与提取的趋势分量。代码实现了滑动窗口下的奇异值分解和分组重构,适用于非线性和非平稳时间序列分析。此方法在气候变化、金融市场和生物医学信号处理等领域有广泛应用。
|
1月前
|
算法
基于模糊控制算法的倒立摆控制系统matlab仿真
本项目构建了一个基于模糊控制算法的倒立摆控制系统,利用MATLAB 2022a实现了从不稳定到稳定状态的转变,并输出了相应的动画和收敛过程。模糊控制器通过对小车位置与摆的角度误差及其变化量进行模糊化处理,依据预设的模糊规则库进行模糊推理并最终去模糊化为精确的控制量,成功地使倒立摆维持在直立位置。该方法无需精确数学模型,适用于处理系统的非线性和不确定性。
基于模糊控制算法的倒立摆控制系统matlab仿真