OpenCV 4.11.0
开源计算机视觉
|
位姿计算问题[182]在于求解旋转和平移,以最小化3D-2D点对应之间的重投影误差。
solvePnP
及相关函数根据一组物体点、其对应的图像投影、相机内参矩阵和畸变系数来估计物体位姿,见下图(更准确地说,相机坐标系的X轴指向右侧,Y轴向下,Z轴向前)。
世界坐标系中表达的点\( \bf{X}_w \)使用透视投影模型\( \Pi \)和相机内参矩阵\( \bf{A} \)(在文献中也记作\( \bf{K} \))投影到图像平面\( \left[ u, v \right] \)
\[ \begin{align*} \begin{bmatrix} u \\ v \\ 1 \end{bmatrix} &= \bf{A} \hspace{0.1em} \Pi \hspace{0.2em} ^{c}\bf{T}_w \begin{bmatrix} X_{w} \\ Y_{w} \\ Z_{w} \\ 1 \end{bmatrix} \\ \begin{bmatrix} u \\ v \\ 1 \end{bmatrix} &= \begin{bmatrix} f_x & 0 & c_x \\ 0 & f_y & c_y \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 \end{bmatrix} \begin{bmatrix} 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{bmatrix} \begin{bmatrix} X_{w} \\ Y_{w} \\ Z_{w} \\ 1 \end{bmatrix} \end{align*} \]
因此,估计的位姿就是旋转向量 (rvec
) 和平移向量 (tvec
),它们允许将世界坐标系中表达的3D点转换到相机坐标系。
\[ \begin{align*} \begin{bmatrix} X_c \\ Y_c \\ Z_c \\ 1 \end{bmatrix} &= \hspace{0.2em} ^{c}\bf{T}_w \begin{bmatrix} X_{w} \\ Y_{w} \\ Z_{w} \\ 1 \end{bmatrix} \\ \begin{bmatrix} X_c \\ Y_c \\ Z_c \\ 1 \end{bmatrix} &= \begin{bmatrix} 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{bmatrix} \begin{bmatrix} X_{w} \\ Y_{w} \\ Z_{w} \\ 1 \end{bmatrix} \end{align*} \]
请参考cv::SolvePnPMethod 枚举文档以了解所有可能的值。下面将详细介绍每种方法。
cv::solveP3P() 使用精确的3个3D-2D点对应关系来计算物体位姿。P3P问题最多有4个解。
cv::solvePnP() 使用不同的方法返回旋转和平移向量,这些向量将物体坐标系中表达的3D点转换为相机坐标系。
cv::solvePnPGeneric() 允许检索所有可能的解。
目前,只有 cv::SOLVEPNP_P3P、cv::SOLVEPNP_AP3P、cv::SOLVEPNP_IPPE、cv::SOLVEPNP_IPPE_SQUARE、cv::SOLVEPNP_SQPNP 可以返回多个解。
cv::solvePnPRansac() 使用 RANSAC 方案计算物体相对于相机坐标系的位姿,以处理离群值。
更多信息可在 [326] 中找到。
姿态细化包括使用非线性最小化方法并从解的初始估计值开始,估计最小化重投影误差的旋转和平移。OpenCV 提供了 cv::solvePnPRefineLM() 和 cv::solvePnPRefineVVS() 用于解决此问题。
cv::solvePnPRefineLM() 使用非线性 Levenberg-Marquardt 最小化方案 [178] [77],当前实现将旋转更新计算为扰动,而不是在 SO(3) 上。
cv::solvePnPRefineVVS() 使用高斯-牛顿非线性最小化方案 [182],并使用指数映射计算旋转部分的更新。