姿态计算概述
姿态计算问题 [170] 包括求解旋转和平移,使三维-二维点对应的重投影误差最小。
solvePnP 和相关函数会根据一组物体点、其对应的图像投影以及摄像机本征矩阵和畸变系数来估计物体姿态,见下图(更准确地说,摄像机帧的 X 轴指向右侧,Y 轴向下,Z 轴向前)。

Camera coordinate system:相机坐标系
World coordinate system:世界坐标系(基坐标系)
利用透视投影模型 Π 和摄像机固有参数矩阵 A(文献中也用 K 表示),将世界帧 Xw 中表示的点投影到图像平面 [u,v] 中:
[
u
v
1
]
=
A
Π
c
T
W
[
X
ω
Y
ω
Z
ω
1
]
\left[ \begin{array}{c} u\\ v\\ 1\\ \end{array} \right] =A\varPi ^cT_W\left[ \begin{array}{c} X_{\omega}\\ Y_{\omega}\\ Z_{\omega}\\ 1\\ \end{array} \right]
uv1
=AΠcTW
XωYωZω1
[
u
v
1
]
=
[
f
x
0
c
x
0
f
y
c
y
0
0
1
]
[
1
0
0
0
0
1
0
0
0
0
1
0
]
[
r
11
r
12
r
13
t
x
r
21
r
22
r
23
t
y
r
31
r
32
r
33
t
z
0
0
0
1
]
[
X
ω
Y
ω
Z
ω
1
]
\left[ \begin{array}{c} u\\ v\\ 1\\ \end{array} \right] =\left[ \begin{matrix} f_x& 0& c_x\\ 0& f_y& c_y\\ 0& 0& 1\\ \end{matrix} \right] \left[ \begin{matrix} 1& 0& \begin{matrix} 0& 0\\ \end{matrix}\\ 0& 1& \begin{matrix} 0& 0\\ \end{matrix}\\ 0& 0& \begin{matrix} 1& 0\\ \end{matrix}\\ \end{matrix} \right] \left[ \begin{matrix} r_{11}& r_{12}& r_{13}& t_x\\ r_{21}& r_{22}& r_{23}& t_y\\ r_{31}& r_{32}& r_{33}& t_z\\ 0& 0& 0& 1\\ \end{matrix} \right] \left[ \begin{array}{c} X_{\omega}\\ Y_{\omega}\\ Z_{\omega}\\ 1\\ \end{array} \right]
uv1
=
fx000fy0cxcy1
100010000010
r11r21r310r12r22r320r13r23r330txtytz1
XωYωZω1
因此,估计姿势就是旋转(rvec)和平移(tvec)矢量,可以将世界帧中表示的三维点转换到摄像机帧中:
[
X
c
Y
c
Z
c
1
]
=
T
w
[
X
ω
Y
ω
Z
ω
1
]
\left[ \begin{array}{c} X_c\\ Y_c\\ Z_c\\ 1\\ \end{array} \right] =T_w\left[ \begin{array}{c} X_{\omega}\\ Y_{\omega}\\ Z_{\omega}\\ 1\\ \end{array} \right]
XcYcZc1
=Tw
XωYωZω1
[ X c Y c Z c 1 ] = [ r 11 r 12 r 13 t x r 21 r 22 r 23 t y r 31 r 32 r 33 t z 0 0 0 1 ] [ X ω Y ω Z ω 1 ] \left[ \begin{array}{c} X_c\\ Y_c\\ Z_c\\ 1\\ \end{array} \right] =\left[ \begin{matrix} r_{11}& r_{12}& r_{13}& t_x\\ r_{21}& r_{22}& r_{23}& t_y\\ r_{31}& r_{32}& r_{33}& t_z\\ 0& 0& 0& 1\\ \end{matrix} \right] \left[ \begin{array}{c} X_{\omega}\\ Y_{\omega}\\ Z_{\omega}\\ 1\\ \end{array} \right] XcYcZc1 = r11r21r310r12r22r320r13r23r330txtytz1 XωYωZω1
姿势计算方法
有关可能值的列表,请参阅 cv::SolvePnPMethod 枚举文档。下面将介绍每种方法的一些细节:
- cv::SOLVEPNP_ITERATIVE 迭代法基于 Levenberg-Marquardt 优化。在这种情况下,该函数会找到使重塑误差(即观察到的投影 "imagePoints "与投影(使用 cv::projectPoints )"objectPoints "之间的距离平方和)最小的姿势。非平面 "objectPoints "的初始解至少需要 6 个点,并使用 DLT 算法。平面 "objectPoints "的初始解至少需要 4 个点,并使用同构分解的姿态。
- cv::SOLVEPNP_P3P 方法基于 X.S. Gao, X.-R. Hou, J. Tang, H.-F. Chang “Complete Solution Classification for the Perspective-Three-Point Problem” ([88])的论文。在这种情况下,函数恰好需要四个对象点和图像点。
- cv::SOLVEPNP_AP3P 方法基于 T. Ke 和 S. Roumeliotis 的论文 “透视-三点问题的高效代数解” ([133]) 。在这种情况下,函数恰好需要四个对象点和图像点。
- cv::SOLVEPNP_EPNP 方法由 F. Moreno-Noguer、V. Lepetit 和 P. Fua 在论文 “EPnP: Efficient Perspective-n-Point Camera Pose Estimation”([145])中提出。
- cv::SOLVEPNP_DLS 已损坏的实现。使用此标志将退回到 EPnP。
该方法基于 J. Hesch 和 S. Roumeliotis 的论文。“PnP 的直接最小二乘法 (DLS) 方法” ([114]). - cv::SOLVEPNP_UPNP 已损坏的实现。使用此标志将退回到 EPnP。
该方法基于 A. Penate-Sanchez、J. Andrade-Cetto、F. Moreno-Noguer 的论文。“Exhaustive Linearization for Robust Camera Pose and Focal Length Estimation” ([199])。在这种情况下,该函数还能估计参数 fx 和 fy,并假设两者具有相同的值。然后用估计的焦距更新 cameraMatrix。 - cv::SOLVEPNP_IPPE 方法基于 T. Collins 和 A. Bartoli 的论文。“基于无限小平面的姿态估计”([52])。此方法需要共面物体点。
- cv::SOLVEPNP_IPPE_SQUARE 方法基于 Toby Collins 和 Adrien Bartoli 的论文。“基于无限小平面的姿态估计”([52])。该方法适用于标记姿态估计。它需要按以下顺序定义 4 个共面物体点:
-
- 点 0:[-squareLength / 2,squareLength / 2,0]
-
- 点 1:[ squareLength / 2, squareLength / 2, 0]
-
- 点 2: [ squareLength / 2,-squareLength / 2,0]
-
- 点 3: [ -squareLength / 2, -squareLength / 2, 0]
- cv::SOLVEPNP_SQPNP 方法基于 G. Terzakis 和 M.Lourakis 的论文 “A Consistently Fast and Globally Optimal Solution to the Perspective-n-Point Problem”([252])。它需要 3 个或更多点。
P3P
**cv::solveP3P()**可以根据精确的 3 个 3D-2D 点对应关系计算物体姿态。一个 P3P 问题最多有 4 个解决方案。
注意
解决方案按照重投影误差(从低到高)排序。
PnP
**cv::solvePnP()**使用不同的方法返回将物体坐标框架中表达的三维点转换到摄像机坐标框架的旋转和平移向量:
- P3P 方法(cv::SOLVEPNP_P3P、cv::SOLVEPNP_AP3P):需要 4 个输入点才能返回唯一解。
- cv::SOLVEPNP_IPPE 输入点必须 >= 4,对象点必须共面。
- cv::SOLVEPNP_IPPE_SQUARE 适用于标记姿态估计的特殊情况。输入点数必须为 4。对象点必须按以下顺序定义:
-
- 点 0:[-squareLength / 2,squareLength / 2,0]
-
- 点 1: [ squareLength / 2, squareLength / 2, 0]
-
- 点 2: [ squareLength / 2,-squareLength / 2,0]
-
- 点 3:[-squareLength / 2,-squareLength / 2,0]
- 对于所有其他标志,输入点数必须大于等于 4,对象点可以是任意配置。
通用 PnP
cv::solvePnPGeneric() 允许检索所有可能的解决方案。
目前,只有 cv::SOLVEPNP_P3P、cv::SOLVEPNP_AP3P、cv::SOLVEPNP_IPPE、cv::SOLVEPNP_IPPE_SQUARE、cv::SOLVEPNP_SQPNP 可以返回多个解。
RANSAC PnP
cv::solvePnPRansac() 使用 RANSAC 方案计算相对于摄像机帧的物体姿态,以处理异常值。
更多信息请参见 [310] 。
姿态细化
姿态细化包括使用非线性最小化方法,从解决方案的初始估计值出发,估算可使重投影误差最小化的旋转和平移。OpenCV 针对此问题提出了 cv::solvePnPRefineLM() 和 cv::solvePnPRefineVVS() 方法。
cv::solvePnPRefineLM() 使用非线性 Levenberg-Marquardt 最小化方案 [166] [68],目前的实现是将旋转更新作为扰动计算,而不是在 SO(3) 上计算。
cv::solvePnPRefineVVS() 使用高斯-牛顿非线性最小化方案 [170] ,并使用指数图计算旋转部分的更新。
注意
至少需要三个 3D-2D 点对应。
2万+

被折叠的 条评论
为什么被折叠?



