OpenCV 4.13.0
开源计算机视觉库 (Open Source Computer Vision)
正在加载...
正在搜索...
未找到匹配项
相机标定与 3D 重建

主题

 鱼眼相机模型
 

详细说明

本节中的函数使用所谓的针孔相机模型。场景的视图是通过使用透视变换将场景的三维点 \(P_w\) 投影到图像平面中,从而形成相应的像素 \(p\)。\(P_w\) 和 \(p\) 都以齐次坐标表示,即分别为三维和二维齐次向量。您将在本节介绍的末尾找到关于射影几何、齐次向量和齐次变换的简要介绍。为了更简洁的表示,我们通常省略“齐次”一词,而直接称之为向量。

由针孔相机模型给出的无畸变透视变换如下所示。

\[s \; p = A \begin{bmatrix} R|t \end{bmatrix} P_w,\]

其中 \(P_w\) 是相对于世界坐标系表示的三维点,\(p\) 是图像平面中的二维像素,\(A\) 是相机内参矩阵,\(R\) 和 \(t\) 是描述从世界坐标系到相机坐标系(或相机帧)坐标变化的旋转和平移,\(s\) 是透视变换的任意缩放,不属于相机模型的一部分。

相机内参矩阵 \(A\)(如 [324] 中使用的符号,通常也表示为 \(K\))将相机坐标系中给出的三维点投影到二维像素坐标,即

\[p = A P_c.\]

相机内参矩阵 \(A\) 由以像素为单位的焦距 \(f_x\) 和 \(f_y\) 以及通常接近图像中心的主点 \((c_x, c_y)\) 组成

\[A = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1},\]

因此

\[s \vecthree{u}{v}{1} = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1} \vecthree{X_c}{Y_c}{Z_c}.\]

内参矩阵不依赖于所查看的场景。因此,一旦估算,只要焦距固定(在变焦镜头的情况下),就可以重复使用。因此,如果相机的图像按某个因子缩放,所有这些参数都需要按相同的因子进行缩放(分别相乘/相除)。

联合旋转平移矩阵 \([R|t]\) 是透视变换和齐次变换的矩阵乘积。3x4 透视变换将相机坐标中表示的三维点映射到图像平面中以归一化相机坐标 \(x' = X_c / Z_c\) 和 \(y' = Y_c / Z_c\) 表示的二维点

\[Z_c \begin{bmatrix} x' \\ y' \\ 1 \end{bmatrix} = \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 \end{bmatrix} \begin{bmatrix} X_c \\ Y_c \\ Z_c \\ 1 \end{bmatrix}.\]

齐次变换由外参 \(R\) 和 \(t\) 编码,表示从世界坐标系 \(w\) 到相机坐标系 \(c\) 的基变换。因此,给定点 \(P\) 在世界坐标系中的表示 \(P_w\),我们通过以下方式获得 \(P\) 在相机坐标系中的表示 \(P_c\)

\[P_c = \begin{bmatrix} R & t \\ 0 & 1 \end{bmatrix} P_w,\]

这个齐次变换由一个 3x3 旋转矩阵 \(R\) 和一个 3x1 平移向量 \(t\) 组成

\[\begin{bmatrix} R & t \\ 0 & 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_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}.\]

结合透视变换和齐次变换,我们得到了将世界坐标系中的三维点映射到图像平面中以归一化相机坐标表示的二维点的透视变换

\[Z_c \begin{bmatrix} x' \\ y' \\ 1 \end{bmatrix} = \begin{bmatrix} R|t \end{bmatrix} \begin{bmatrix} X_w \\ Y_w \\ Z_w \\ 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 \end{bmatrix} \begin{bmatrix} X_w \\ Y_w \\ Z_w \\ 1 \end{bmatrix},\]

其中 \(x' = X_c / Z_c\) 和 \(y' = Y_c / Z_c\)。将内参和外参的方程放在一起,我们可以将 \(s \; p = A \begin{bmatrix} R|t \end{bmatrix} P_w\) 写成

\[s \vecthree{u}{v}{1} = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1} \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 \end{bmatrix} \begin{bmatrix} X_w \\ Y_w \\ Z_w \\ 1 \end{bmatrix}.\]

如果 \(Z_c \ne 0\),则上述变换等价于以下形式:

\[\begin{bmatrix} u \\ v \end{bmatrix} = \begin{bmatrix} f_x X_c/Z_c + c_x \\ f_y Y_c/Z_c + c_y \end{bmatrix}\]

其中

\[\vecthree{X_c}{Y_c}{Z_c} = \begin{bmatrix} R|t \end{bmatrix} \begin{bmatrix} X_w \\ Y_w \\ Z_w \\ 1 \end{bmatrix}.\]

下图展示了针孔相机模型。

针孔相机模型

实际镜头通常存在一些畸变,主要是径向畸变和轻微的切向畸变。因此,上述模型被扩展为

\[\begin{bmatrix} u \\ v \end{bmatrix} = \begin{bmatrix} f_x x'' + c_x \\ f_y y'' + c_y \end{bmatrix}\]

其中

\[\begin{bmatrix} x'' \\ y'' \end{bmatrix} = \begin{bmatrix} x' \frac{1 + k_1 r^2 + k_2 r^4 + k_3 r^6}{1 + k_4 r^2 + k_5 r^4 + k_6 r^6} + 2 p_1 x' y' + p_2(r^2 + 2 x'^2) + s_1 r^2 + s_2 r^4 \\ y' \frac{1 + k_1 r^2 + k_2 r^4 + k_3 r^6}{1 + k_4 r^2 + k_5 r^4 + k_6 r^6} + p_1 (r^2 + 2 y'^2) + 2 p_2 x' y' + s_3 r^2 + s_4 r^4 \\ \end{bmatrix}\]

其中

\[r^2 = x'^2 + y'^2\]

\[\begin{bmatrix} x'\\ y' \end{bmatrix} = \begin{bmatrix} X_c/Z_c \\ Y_c/Z_c \end{bmatrix},\]

如果 \(Z_c \ne 0\)。

畸变参数包括径向系数 \(k_1\)、\(k_2\)、\(k_3\)、\(k_4\)、\(k_5\) 和 \(k_6\),\(p_1\) 和 \(p_2\) 是切向畸变系数,\(s_1\)、\(s_2\)、\(s_3\) 和 \(s_4\) 是薄棱镜畸变系数。OpenCV 中不考虑更高阶的系数。

接下来的图展示了两种常见的径向畸变类型:桶形畸变(\( 1 + k_1 r^2 + k_2 r^4 + k_3 r^6 \) 单调递减)和枕形畸变(\( 1 + k_1 r^2 + k_2 r^4 + k_3 r^6 \) 单调递增)。对于真实镜头,径向畸变总是单调的,如果估算器产生非单调结果,则应视为标定失败。更一般地,径向畸变必须是单调的,并且畸变函数必须是双射的。失败的估算结果可能在图像中心附近看起来很好,但在例如 AR/SFM 应用中会表现不佳。OpenCV 相机标定中使用的优化方法不包括这些约束,因为该框架不支持所需的整数规划和多项式不等式。有关更多信息,请参阅问题 #15992

在某些情况下,图像传感器可能会倾斜以聚焦相机前方的倾斜平面(谢姆普鲁格原理)。这对于粒子图像测速(PIV)或激光扇形三角测量很有用。倾斜导致 \(x''\) 和 \(y''\) 的透视畸变。这种畸变可以通过以下方式建模,例如参见 [177]

\[\begin{bmatrix} u \\ v \end{bmatrix} = \begin{bmatrix} f_x x''' + c_x \\ f_y y''' + c_y \end{bmatrix},\]

其中

\[s\vecthree{x'''}{y'''}{1} = \vecthreethree{R_{33}(\tau_x, \tau_y)}{0}{-R_{13}(\tau_x, \tau_y)} {0}{R_{33}(\tau_x, \tau_y)}{-R_{23}(\tau_x, \tau_y)} {0}{0}{1} R(\tau_x, \tau_y) \vecthree{x''}{y''}{1}\]

矩阵 \(R(\tau_x, \tau_y)\) 分别由两个角参数为 \(\tau_x\) 和 \(\tau_y\) 的旋转定义,

\[ R(\tau_x, \tau_y) = \vecthreethree{\cos(\tau_y)}{0}{-\sin(\tau_y)}{0}{1}{0}{\sin(\tau_y)}{0}{\cos(\tau_y)} \vecthreethree{1}{0}{0}{0}{\cos(\tau_x)}{\sin(\tau_x)}{0}{-\sin(\tau_x)}{\cos(\tau_x)} = \vecthreethree{\cos(\tau_y)}{\sin(\tau_y)\sin(\tau_x)}{-\sin(\tau_y)\cos(\tau_x)} {0}{\cos(\tau_x)}{\sin(\tau_x)} {\sin(\tau_y)}{-\cos(\tau_y)\sin(\tau_x)}{\cos(\tau_y)\cos(\tau_x)}. \]

在下面的函数中,系数以以下形式传递或返回

\[(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6 [, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]])\]

向量。也就是说,如果向量包含四个元素,则表示 \(k_3=0\)。畸变系数不依赖于所查看的场景。因此,它们也属于相机内参。并且它们在捕获图像分辨率方面保持不变。例如,如果相机已在 320 x 240 分辨率的图像上进行标定,则对于来自同一相机的 640 x 480 图像,可以使用完全相同的畸变系数,而 \(f_x\)、\(f_y\)、\(c_x\) 和 \(c_y\) 需要进行适当的缩放。

下面的函数使用上述模型执行以下操作:

齐次坐标
齐次坐标是射影几何中使用的一种坐标系。它们的使用允许用有限坐标表示无穷远处的点,并与笛卡尔坐标相比简化了公式,例如,它们具有仿射变换可以表示为线性齐次变换的优点。

通过在 n 维笛卡尔向量 \(P\) 后附加 1 来获得齐次向量 \(P_h\),例如对于三维笛卡尔向量,映射 \(P \rightarrow P_h\) 为

\[\begin{bmatrix} X \\ Y \\ Z \end{bmatrix} \rightarrow \begin{bmatrix} X \\ Y \\ Z \\ 1 \end{bmatrix}.\]

对于逆映射 \(P_h \rightarrow P\),将齐次向量的所有元素除以其最后一个元素,例如对于三维齐次向量,通过以下方式获得其二维笛卡尔对应物

\[\begin{bmatrix} X \\ Y \\ W \end{bmatrix} \rightarrow \begin{bmatrix} X / W \\ Y / W \end{bmatrix},\]

如果 \(W \ne 0\)。

由于这种映射,齐次点 \(P_h\) 的所有倍数 \(k P_h\)(其中 \(k \ne 0\))都代表相同的点 \(P_h\)。对这一属性的直观理解是,在透视变换下,\(P_h\) 的所有倍数都映射到同一点。这是针孔相机所做的物理观察,因为通过相机针孔的射线上的所有点都投影到同一个图像点,例如,上图中针孔相机模型红色射线上的所有点都将映射到同一个图像坐标。这一属性也是针孔相机模型方程中比例模糊性 s 的来源。

如前所述,通过使用齐次坐标,我们可以将任何由 \(R\) 和 \(t\) 参数化的基变换表示为线性变换,例如,从坐标系 0 到坐标系 1 的基变换变为

\[P_1 = R P_0 + t \rightarrow P_{h_1} = \begin{bmatrix} R & t \\ 0 & 1 \end{bmatrix} P_{h_0}.\]

齐次变换,对象帧/相机帧
使用以下符号可以轻松实现基变换或计算从一个帧到另一个帧的三维坐标

\[ \mathbf{X}_c = \hspace{0.2em} {}^{c}\mathbf{T}_o \hspace{0.2em} \mathbf{X}_o \]

\[ \begin{bmatrix} X_c \\ Y_c \\ Z_c \\ 1 \end{bmatrix} = \begin{bmatrix} {}^{c}\mathbf{R}_o & {}^{c}\mathbf{t}_o \\ 0_{1 \times 3} & 1 \end{bmatrix} \begin{bmatrix} X_o \\ Y_o \\ Z_o \\ 1 \end{bmatrix} \]

对于在对象帧中表示的三维点(\( \mathbf{X}_o \)),齐次变换矩阵 \( {}^{c}\mathbf{T}_o \) 允许计算相机帧中对应的坐标(\( \mathbf{X}_c \))。此变换矩阵由一个 3x3 旋转矩阵 \( {}^{c}\mathbf{R}_o \) 和一个 3x1 平移向量 \( {}^{c}\mathbf{t}_o \) 组成。3x1 平移向量 \( {}^{c}\mathbf{t}_o \) 是对象帧在相机帧中的位置,3x3 旋转矩阵 \( {}^{c}\mathbf{R}_o \) 是对象帧在相机帧中的方向。

有了这个简单的符号,很容易串联变换。例如,计算在对象帧中表示的点在世界帧中的三维坐标可以通过以下方式完成

\[ \mathbf{X}_w = \hspace{0.2em} {}^{w}\mathbf{T}_c \hspace{0.2em} {}^{c}\mathbf{T}_o \hspace{0.2em} \mathbf{X}_o = {}^{w}\mathbf{T}_o \hspace{0.2em} \mathbf{X}_o \]

类似地,逆变换可以通过以下方式完成

\[ \mathbf{X}_o = \hspace{0.2em} {}^{o}\mathbf{T}_c \hspace{0.2em} \mathbf{X}_c = \left( {}^{c}\mathbf{T}_o \right)^{-1} \hspace{0.2em} \mathbf{X}_c \]

齐次变换矩阵的逆是

\[ {}^{o}\mathbf{T}_c = \left( {}^{c}\mathbf{T}_o \right)^{-1} = \begin{bmatrix} {}^{c}\mathbf{R}^{\top}_o & - \hspace{0.2em} {}^{c}\mathbf{R}^{\top}_o \hspace{0.2em} {}^{c}\mathbf{t}_o \\ 0_{1 \times 3} & 1 \end{bmatrix} \]

可以注意到,3x3 旋转矩阵的逆直接是其转置矩阵。

透视投影,从对象帧到相机帧

此图总结了整个过程。solvePnP 函数或从 fiducial 标记检测返回的对象姿态就是这个 \( {}^{c}\mathbf{T}_o \) 变换。

相机内参矩阵 \( \mathbf{K} \) 允许将相机帧中表示的三维点投影到图像平面上,假设采用透视投影模型(针孔相机模型)。从经典图像处理函数中提取的图像坐标假定为 (u,v) 左上角坐标系。

注意

相机镜头规格中的内参
在处理工业相机时,相机内参矩阵或更精确地说 \( \left(f_x, f_y \right) \) 可以从相机规格中推导、近似得出

\[ f_x = \frac{f_{\text{mm}}}{\text{pixel_size_in_mm}} = \frac{f_{\text{mm}}}{\text{sensor_size_in_mm} / \text{nb_pixels}} \]

同样,物理焦距可以从视角推导出来

\[ f_{\text{mm}} = \frac{\text{sensor_size_in_mm}}{2 \times \tan{\frac{\text{fov}}{2}}} \]

后者在进行渲染软件以模拟物理相机设备时可能很有用。

注意

附加参考资料、注意事项

注意
  • 本模块中的许多函数都接受相机内参矩阵作为输入参数。尽管所有函数都假定此参数具有相同的结构,但它们可能以不同的名称命名。然而,参数的描述将清楚地表明需要具有上述结构的相机内参矩阵。
  • 可以在 opencv_source_code/samples/cpp/3calibration.cpp 中找到一个水平位置的 3 个摄像头的标定示例
  • 可以在 opencv_source_code/samples/cpp/calibration.cpp 中找到一个基于图像序列的标定示例
  • 可以在 opencv_source_code/samples/cpp/build3dmodel.cpp 中找到一个用于 3D 重建的标定示例
  • 可以在 opencv_source_code/samples/cpp/stereo_calib.cpp 中找到一个立体标定示例
  • 可以在 opencv_source_code/samples/cpp/stereo_match.cpp 中找到一个立体匹配示例
  • (Python) 可以在 opencv_source_code/samples/python/calibrate.py 中找到一个相机标定示例

结构体  cv::CirclesGridFinderParameters
 
类  cv::LMSolver
 
类  cv::StereoBM
 使用块匹配算法计算立体对应关系的类,由 K. Konolige 引入并贡献给 OpenCV。更多...
 
类  cv::StereoMatcher
 立体对应算法的基类。更多...
 
类  cv::StereoSGBM
 该类实现了改进的 H. Hirschmuller 算法 [129],该算法与原始算法的区别如下:更多...
 
结构体  cv::UsacParams
 

类型定义 (Typedefs)

typedef CirclesGridFinderParameters cv::CirclesGridFinderParameters2
 

枚举

enum  {
  cv::LMEDS = 4 ,
  cv::RANSAC = 8 ,
  cv::RHO = 16 ,
  cv::USAC_DEFAULT = 32 ,
  cv::USAC_PARALLEL = 33 ,
  cv::USAC_FM_8PTS = 34 ,
  cv::USAC_FAST = 35 ,
  cv::USAC_ACCURATE = 36 ,
  cv::USAC_PROSAC = 37 ,
  cv::USAC_MAGSAC = 38
}
 鲁棒估计算法的类型 更多...
 
enum  {
  cv::CALIB_CB_ADAPTIVE_THRESH = 1 ,
  cv::CALIB_CB_NORMALIZE_IMAGE = 2 ,
  cv::CALIB_CB_FILTER_QUADS = 4 ,
  cv::CALIB_CB_FAST_CHECK = 8 ,
  cv::CALIB_CB_EXHAUSTIVE = 16 ,
  cv::CALIB_CB_ACCURACY = 32 ,
  cv::CALIB_CB_LARGER = 64 ,
  cv::CALIB_CB_MARKER = 128 ,
  cv::CALIB_CB_PLAIN = 256
}
 
enum  {
  cv::CALIB_CB_SYMMETRIC_GRID = 1 ,
  cv::CALIB_CB_ASYMMETRIC_GRID = 2 ,
  cv::CALIB_CB_CLUSTERING = 4
}
 
enum  {
  cv::CALIB_NINTRINSIC = 18 ,
  cv::CALIB_USE_INTRINSIC_GUESS = 0x00001 ,
  cv::CALIB_FIX_ASPECT_RATIO = 0x00002 ,
  cv::CALIB_FIX_PRINCIPAL_POINT = 0x00004 ,
  cv::CALIB_ZERO_TANGENT_DIST = 0x00008 ,
  cv::CALIB_FIX_FOCAL_LENGTH = 0x00010 ,
  cv::CALIB_FIX_K1 = 0x00020 ,
  cv::CALIB_FIX_K2 = 0x00040 ,
  cv::CALIB_FIX_K3 = 0x00080 ,
  cv::CALIB_FIX_K4 = 0x00800 ,
  cv::CALIB_FIX_K5 = 0x01000 ,
  cv::CALIB_FIX_K6 = 0x02000 ,
  cv::CALIB_RATIONAL_MODEL = 0x04000 ,
  cv::CALIB_THIN_PRISM_MODEL = 0x08000 ,
  cv::CALIB_FIX_S1_S2_S3_S4 = 0x10000 ,
  cv::CALIB_TILTED_MODEL = 0x40000 ,
  cv::CALIB_FIX_TAUX_TAUY = 0x80000 ,
  cv::CALIB_USE_QR = 0x100000 ,
  cv::CALIB_FIX_TANGENT_DIST = 0x200000 ,
  cv::CALIB_FIX_INTRINSIC = 0x00100 ,
  cv::CALIB_SAME_FOCAL_LENGTH = 0x00200 ,
  cv::CALIB_ZERO_DISPARITY = 0x00400 ,
  cv::CALIB_USE_LU = (1 << 17) ,
  cv::CALIB_USE_EXTRINSIC_GUESS = (1 << 22)
}
 
enum  {
  cv::FM_7POINT = 1 ,
  cv::FM_8POINT = 2 ,
  cv::FM_LMEDS = 4 ,
  cv::FM_RANSAC = 8
}
 寻找基础矩阵的算法 更多...
 
enum  cv::HandEyeCalibrationMethod {
  cv::CALIB_HAND_EYE_TSAI = 0 ,
  cv::CALIB_HAND_EYE_PARK = 1 ,
  cv::CALIB_HAND_EYE_HORAUD = 2 ,
  cv::CALIB_HAND_EYE_ANDREFF = 3 ,
  cv::CALIB_HAND_EYE_DANIILIDIS = 4
}
 
enum  cv::LocalOptimMethod {
  cv::LOCAL_OPTIM_NULL =0 ,
  cv::LOCAL_OPTIM_INNER_LO =1 ,
  cv::LOCAL_OPTIM_INNER_AND_ITER_LO =2 ,
  cv::LOCAL_OPTIM_GC =3 ,
  cv::LOCAL_OPTIM_SIGMA =4
}
 
enum  cv::NeighborSearchMethod {
  cv::NEIGH_FLANN_KNN =0 ,
  cv::NEIGH_GRID =1 ,
  cv::NEIGH_FLANN_RADIUS =2
}
 
enum  cv::PolishingMethod {
  cv::NONE_POLISHER =0 ,
  cv::LSQ_POLISHER =1 ,
  cv::MAGSAC =2 ,
  cv::COV_POLISHER =3
}
 
enum  cv::RobotWorldHandEyeCalibrationMethod {
  cv::CALIB_ROBOT_WORLD_HAND_EYE_SHAH = 0 ,
  cv::CALIB_ROBOT_WORLD_HAND_EYE_LI = 1
}
 
enum  cv::SamplingMethod {
  cv::SAMPLING_UNIFORM =0 ,
  cv::SAMPLING_PROGRESSIVE_NAPSAC =1 ,
  cv::SAMPLING_NAPSAC =2 ,
  cv::SAMPLING_PROSAC =3
}
 
enum  cv::ScoreMethod {
  cv::SCORE_METHOD_RANSAC =0 ,
  cv::SCORE_METHOD_MSAC =1 ,
  cv::SCORE_METHOD_MAGSAC =2 ,
  cv::SCORE_METHOD_LMEDS =3
}
 
enum  cv::SolvePnPMethod {
  cv::SOLVEPNP_ITERATIVE = 0 ,
  cv::SOLVEPNP_EPNP = 1 ,
  cv::SOLVEPNP_P3P = 2 ,
  cv::SOLVEPNP_DLS = 3 ,
  cv::SOLVEPNP_UPNP = 4 ,
  cv::SOLVEPNP_AP3P = 5 ,
  cv::SOLVEPNP_IPPE = 6 ,
  cv::SOLVEPNP_IPPE_SQUARE = 7 ,
  cv::SOLVEPNP_SQPNP = 8
}
 
enum  cv::UndistortTypes {
  cv::PROJ_SPHERICAL_ORTHO = 0 ,
  cv::PROJ_SPHERICAL_EQRECT = 1
}
 cv::undistort 模式 更多...
 

函数

double cv::calibrateCamera (InputArrayOfArrays objectPoints, InputArrayOfArrays imagePoints, Size imageSize, InputOutputArray cameraMatrix, InputOutputArray distCoeffs, OutputArrayOfArrays rvecs, OutputArrayOfArrays tvecs, int flags=0, TermCriteria criteria=TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, DBL_EPSILON))
 
double cv::calibrateCamera (InputArrayOfArrays objectPoints, InputArrayOfArrays imagePoints, Size imageSize, InputOutputArray cameraMatrix, InputOutputArray distCoeffs, OutputArrayOfArrays rvecs, OutputArrayOfArrays tvecs, OutputArray stdDeviationsIntrinsics, OutputArray stdDeviationsExtrinsics, OutputArray perViewErrors, int flags=0, TermCriteria criteria=TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, DBL_EPSILON))
 从标定图案的多个视图中寻找相机内参和外参参数。
 
double cv::calibrateCameraRO (InputArrayOfArrays objectPoints, InputArrayOfArrays imagePoints, Size imageSize, int iFixedPoint, InputOutputArray cameraMatrix, InputOutputArray distCoeffs, OutputArrayOfArrays rvecs, OutputArrayOfArrays tvecs, OutputArray newObjPoints, int flags=0, TermCriteria criteria=TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, DBL_EPSILON))
 
double cv::calibrateCameraRO (InputArrayOfArrays objectPoints, InputArrayOfArrays imagePoints, Size imageSize, int iFixedPoint, InputOutputArray cameraMatrix, InputOutputArray distCoeffs, OutputArrayOfArrays rvecs, OutputArrayOfArrays tvecs, OutputArray newObjPoints, OutputArray stdDeviationsIntrinsics, OutputArray stdDeviationsExtrinsics, OutputArray stdDeviationsObjPoints, OutputArray perViewErrors, int flags=0, TermCriteria criteria=TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, DBL_EPSILON))
 从标定图案的多个视图中寻找相机内参和外参参数。
 
void cv::calibrateHandEye (InputArrayOfArrays R_gripper2base, InputArrayOfArrays t_gripper2base, InputArrayOfArrays R_target2cam, InputArrayOfArrays t_target2cam, OutputArray R_cam2gripper, OutputArray t_cam2gripper, HandEyeCalibrationMethod method=CALIB_HAND_EYE_TSAI)
 计算手眼标定:\(_{}^{g}\textrm{T}_c\)。
 
void cv::calibrateRobotWorldHandEye (InputArrayOfArrays R_world2cam, InputArrayOfArrays t_world2cam, InputArrayOfArrays R_base2gripper, InputArrayOfArrays t_base2gripper, OutputArray R_base2world, OutputArray t_base2world, OutputArray R_gripper2cam, OutputArray t_gripper2cam, RobotWorldHandEyeCalibrationMethod method=CALIB_ROBOT_WORLD_HAND_EYE_SHAH)
 计算机器人-世界/手眼标定:\(_{}^{w}\textrm{T}_b\) 和 \(_{}^{c}\textrm{T}_g\)。
 
void cv::calibrationMatrixValues (InputArray cameraMatrix, Size imageSize, double apertureWidth, double apertureHeight, double &fovx, double &fovy, double &focalLength, Point2d &principalPoint, double &aspectRatio)
 从相机内参矩阵计算有用的相机特性。
 
bool cv::checkChessboard (InputArray img, Size size)
 
void cv::composeRT (InputArray rvec1, InputArray tvec1, InputArray rvec2, InputArray tvec2, OutputArray rvec3, OutputArray tvec3, OutputArray dr3dr1=noArray(), OutputArray dr3dt1=noArray(), OutputArray dr3dr2=noArray(), OutputArray dr3dt2=noArray(), OutputArray dt3dr1=noArray(), OutputArray dt3dt1=noArray(), OutputArray dt3dr2=noArray(), OutputArray dt3dt2=noArray())
 结合两个旋转和平移变换。
 
void cv::computeCorrespondEpilines (InputArray points, int whichImage, InputArray F, OutputArray lines)
 对于立体像对中一幅图像上的点,计算另一幅图像中相应的极线。
 
void cv::convertPointsFromHomogeneous (InputArray src, OutputArray dst)
 将点从齐次空间转换为欧几里得空间。
 
void cv::convertPointsHomogeneous (InputArray src, OutputArray dst)
 在齐次坐标之间转换点。
 
void cv::convertPointsToHomogeneous (InputArray src, OutputArray dst)
 将点从欧几里得空间转换为齐次空间。
 
void cv::correctMatches (InputArray F, InputArray points1, InputArray points2, OutputArray newPoints1, OutputArray newPoints2)
 精细化对应点的坐标。
 
void cv::decomposeEssentialMat (InputArray E, OutputArray R1, OutputArray R2, OutputArray t)
 将本质矩阵分解为可能的旋转和平移。
 
int cv::decomposeHomographyMat (InputArray H, InputArray K, OutputArrayOfArrays rotations, OutputArrayOfArrays translations, OutputArrayOfArrays normals)
 将单应性矩阵分解为旋转、平移和平面法线。
 
void cv::decomposeProjectionMatrix (InputArray projMatrix, OutputArray cameraMatrix, OutputArray rotMatrix, OutputArray transVect, OutputArray rotMatrixX=noArray(), OutputArray rotMatrixY=noArray(), OutputArray rotMatrixZ=noArray(), OutputArray eulerAngles=noArray())
 将投影矩阵分解为旋转矩阵和相机内参矩阵。
 
void cv::drawChessboardCorners (InputOutputArray image, Size patternSize, InputArray corners, bool patternWasFound)
 渲染检测到的棋盘格角点。
 
void cv::drawFrameAxes (InputOutputArray image, InputArray cameraMatrix, InputArray distCoeffs, InputArray rvec, InputArray tvec, float length, int thickness=3)
 根据姿态估计绘制世界/物体坐标系的轴。
 
cv::Mat cv::estimateAffine2D (InputArray from, InputArray to, OutputArray inliers=noArray(), int method=RANSAC, double ransacReprojThreshold=3, size_t maxIters=2000, double confidence=0.99, size_t refineIters=10)
 计算两个 2D 点集之间的最佳仿射变换。
 
cv::Mat cv::estimateAffine2D (InputArray pts1, InputArray pts2, OutputArray inliers, const UsacParams &params)
 
cv::Mat cv::estimateAffine3D (InputArray src, InputArray dst, double *scale=nullptr, bool force_rotation=true)
 计算两个 3D 点集之间的最佳仿射变换。
 
int cv::estimateAffine3D (InputArray src, InputArray dst, OutputArray out, OutputArray inliers, double ransacThreshold=3, double confidence=0.99)
 计算两个 3D 点集之间的最佳仿射变换。
 
cv::Mat cv::estimateAffinePartial2D (InputArray from, InputArray to, OutputArray inliers=noArray(), int method=RANSAC, double ransacReprojThreshold=3, size_t maxIters=2000, double confidence=0.99, size_t refineIters=10)
 计算两个 2D 点集之间的具有 4 个自由度的最佳受限仿射变换。
 
Scalar cv::estimateChessboardSharpness (InputArray image, Size patternSize, InputArray corners, float rise_distance=0.8F, bool vertical=false, OutputArray sharpness=noArray())
 估计检测到的棋盘格的清晰度。
 
cv::Vec2d cv::estimateTranslation2D (InputArray from, InputArray to, OutputArray inliers=noArray(), int method=RANSAC, double ransacReprojThreshold=3, size_t maxIters=2000, double confidence=0.99, size_t refineIters=0)
 计算两个 2D 点集之间的纯 2D 平移。
 
int cv::estimateTranslation3D (InputArray src, InputArray dst, OutputArray out, OutputArray inliers, double ransacThreshold=3, double confidence=0.99)
 计算两个 3D 点集之间的最佳平移。
 
void cv::filterHomographyDecompByVisibleRefpoints (InputArrayOfArrays rotations, InputArrayOfArrays normals, InputArray beforePoints, InputArray afterPoints, OutputArray possibleSolutions, InputArray pointsMask=noArray())
 基于附加信息过滤单应性分解结果。
 
void cv::filterSpeckles (InputOutputArray img, double newVal, int maxSpeckleSize, double maxDiff, InputOutputArray buf=noArray())
 过滤视差图中的细小噪声点(斑点)。
 
bool cv::find4QuadCornerSubpix (InputArray img, InputOutputArray corners, Size region_size)
 寻找棋盘格角点的亚像素级精确位置
 
bool cv::findChessboardCorners (InputArray image, Size patternSize, OutputArray corners, int flags=CALIB_CB_ADAPTIVE_THRESH+CALIB_CB_NORMALIZE_IMAGE)
 寻找棋盘格内角点的位置。
 
bool cv::findChessboardCornersSB (InputArray image, Size patternSize, OutputArray corners, int flags, OutputArray meta)
 使用基于扇区的方法寻找棋盘格内角点的位置。
 
bool cv::findChessboardCornersSB (InputArray image, Size patternSize, OutputArray corners, int flags=0)
 
bool cv::findCirclesGrid (InputArray image, Size patternSize, OutputArray centers, int flags, const Ptr< FeatureDetector > &blobDetector, const CirclesGridFinderParameters &parameters)
 寻找圆网格中的中心点。
 
bool cv::findCirclesGrid (InputArray image, Size patternSize, OutputArray centers, int flags=CALIB_CB_SYMMETRIC_GRID, const Ptr< FeatureDetector > &blobDetector=SimpleBlobDetector::create())
 
Mat cv::findEssentialMat (InputArray points1, InputArray points2, double focal, Point2d pp, int method, double prob, double threshold, OutputArray mask)
 
Mat cv::findEssentialMat (InputArray points1, InputArray points2, double focal=1.0, Point2d pp=Point2d(0, 0), int method=RANSAC, double prob=0.999, double threshold=1.0, int maxIters=1000, OutputArray mask=noArray())
 
Mat cv::findEssentialMat (InputArray points1, InputArray points2, InputArray cameraMatrix, int method, double prob, double threshold, OutputArray mask)
 
Mat cv::findEssentialMat (InputArray points1, InputArray points2, InputArray cameraMatrix, int method=RANSAC, double prob=0.999, double threshold=1.0, int maxIters=1000, OutputArray mask=noArray())
 根据两幅图像中的对应点计算本质矩阵。
 
Mat cv::findEssentialMat (InputArray points1, InputArray points2, InputArray cameraMatrix1, InputArray cameraMatrix2, InputArray dist_coeff1, InputArray dist_coeff2, OutputArray mask, const UsacParams &params)
 
Mat cv::findEssentialMat (InputArray points1, InputArray points2, InputArray cameraMatrix1, InputArray distCoeffs1, InputArray cameraMatrix2, InputArray distCoeffs2, int method=RANSAC, double prob=0.999, double threshold=1.0, OutputArray mask=noArray())
 根据两幅图像(可能来自两台不同的相机)中的对应点计算本质矩阵。
 
Mat cv::findFundamentalMat (InputArray points1, InputArray points2, int method, double ransacReprojThreshold, double confidence, int maxIters, OutputArray mask=noArray())
 根据两幅图像中的对应点计算基础矩阵。
 
Mat cv::findFundamentalMat (InputArray points1, InputArray points2, int method=FM_RANSAC, double ransacReprojThreshold=3., double confidence=0.99, OutputArray mask=noArray())
 
Mat cv::findFundamentalMat (InputArray points1, InputArray points2, OutputArray mask, const UsacParams &params)
 
Mat cv::findFundamentalMat (InputArray points1, InputArray points2, OutputArray mask, int method=FM_RANSAC, double ransacReprojThreshold=3., double confidence=0.99)
 
Mat cv::findHomography (InputArray srcPoints, InputArray dstPoints, int method=0, double ransacReprojThreshold=3, OutputArray mask=noArray(), const int maxIters=2000, const double confidence=0.995)
 寻找两个平面之间的透视变换。
 
Mat cv::findHomography (InputArray srcPoints, InputArray dstPoints, OutputArray mask, const UsacParams &params)
 
Mat cv::findHomography (InputArray srcPoints, InputArray dstPoints, OutputArray mask, int method=0, double ransacReprojThreshold=3)
 
Mat cv::getDefaultNewCameraMatrix (InputArray cameraMatrix, Size imgsize=Size(), bool centerPrincipalPoint=false)
 返回默认的新相机矩阵。
 
Mat cv::getOptimalNewCameraMatrix (InputArray cameraMatrix, InputArray distCoeffs, Size imageSize, double alpha, Size newImgSize=Size(), Rect *validPixROI=0, bool centerPrincipalPoint=false)
 基于自由缩放参数返回新的相机内参矩阵。
 
Rect cv::getValidDisparityROI (Rect roi1, Rect roi2, int minDisparity, int numberOfDisparities, int blockSize)
 从校正图像的有效 ROI(由 stereoRectify 返回)计算有效视差 ROI
 
Mat cv::initCameraMatrix2D (InputArrayOfArrays objectPoints, InputArrayOfArrays imagePoints, Size imageSize, double aspectRatio=1.0)
 从 3D-2D 点对应关系寻找初始相机内参矩阵。
 
void cv::initInverseRectificationMap (InputArray cameraMatrix, InputArray distCoeffs, InputArray R, InputArray newCameraMatrix, const Size &size, int m1type, OutputArray map1, OutputArray map2)
 计算投影和逆校正变换图。本质上,这是 initUndistortRectifyMap 的逆运算,用于适应投影仪-相机对中的投影仪(“逆相机”)的立体校正。
 
void cv::initUndistortRectifyMap (InputArray cameraMatrix, InputArray distCoeffs, InputArray R, InputArray newCameraMatrix, Size size, int m1type, OutputArray map1, OutputArray map2)
 计算去畸变和校正变换映射。
 
float cv::initWideAngleProjMap (InputArray cameraMatrix, InputArray distCoeffs, Size imageSize, int destImageWidth, int m1type, OutputArray map1, OutputArray map2, enum UndistortTypes projType=PROJ_SPHERICAL_EQRECT, double alpha=0)
 初始化用于广角图像 remap 的映射。
 
static float cv::initWideAngleProjMap (InputArray cameraMatrix, InputArray distCoeffs, Size imageSize, int destImageWidth, int m1type, OutputArray map1, OutputArray map2, int projType, double alpha=0)
 
void cv::matMulDeriv (InputArray A, InputArray B, OutputArray dABdA, OutputArray dABdB)
 针对相乘的每个矩阵计算矩阵乘积的偏导数。
 
void cv::projectPoints (InputArray objectPoints, InputArray rvec, InputArray tvec, InputArray cameraMatrix, InputArray distCoeffs, OutputArray imagePoints, OutputArray jacobian=noArray(), double aspectRatio=0)
 将 3D 点投影到图像平面。
 
int cv::recoverPose (InputArray E, InputArray points1, InputArray points2, InputArray cameraMatrix, OutputArray R, OutputArray t, double distanceThresh, InputOutputArray mask=noArray(), OutputArray triangulatedPoints=noArray())
 
int cv::recoverPose (InputArray E, InputArray points1, InputArray points2, InputArray cameraMatrix, OutputArray R, OutputArray t, InputOutputArray mask=noArray())
 根据估算的本质矩阵和两幅图像中的对应点,通过手性检查(chirality check)恢复相机的相对旋转和平移。返回通过检查的内点数量。
 
int cv::recoverPose (InputArray E, InputArray points1, InputArray points2, OutputArray R, OutputArray t, double focal=1.0, Point2d pp=Point2d(0, 0), InputOutputArray mask=noArray())
 
int cv::recoverPose (InputArray points1, InputArray points2, InputArray cameraMatrix1, InputArray distCoeffs1, InputArray cameraMatrix2, InputArray distCoeffs2, OutputArray E, OutputArray R, OutputArray t, int method=cv::RANSAC, double prob=0.999, double threshold=1.0, InputOutputArray mask=noArray())
 利用手性检查(cheirality check),从两台不同相机的两幅图像中的对应点恢复相机的相对旋转和平移。返回通过检查的内点(inliers)数量。
 
float cv::rectify3Collinear (InputArray cameraMatrix1, InputArray distCoeffs1, InputArray cameraMatrix2, InputArray distCoeffs2, InputArray cameraMatrix3, InputArray distCoeffs3, InputArrayOfArrays imgpt1, InputArrayOfArrays imgpt3, Size imageSize, InputArray R12, InputArray T12, InputArray R13, InputArray T13, OutputArray R1, OutputArray R2, OutputArray R3, OutputArray P1, OutputArray P2, OutputArray P3, OutputArray Q, double alpha, Size newImgSize, Rect *roi1, Rect *roi2, int flags)
 计算三头相机的校正变换,其中所有相机头都在同一直线上。
 
void cv::reprojectImageTo3D (InputArray disparity, OutputArray _3dImage, InputArray Q, bool handleMissingValues=false, int ddepth=-1)
 将视差图像重新投影到 3D 空间。
 
void cv::Rodrigues (InputArray src, OutputArray dst, OutputArray jacobian=noArray())
 在旋转矩阵与旋转向量之间进行转换。
 
Vec3d cv::RQDecomp3x3 (InputArray src, OutputArray mtxR, OutputArray mtxQ, OutputArray Qx=noArray(), OutputArray Qy=noArray(), OutputArray Qz=noArray())
 计算 3x3 矩阵的 RQ 分解。
 
double cv::sampsonDistance (InputArray pt1, InputArray pt2, InputArray F)
 计算两点之间的 Sampson 距离。
 
int cv::solveP3P (InputArray objectPoints, InputArray imagePoints, InputArray cameraMatrix, InputArray distCoeffs, OutputArrayOfArrays rvecs, OutputArrayOfArrays tvecs, int flags)
 3 组 3D-2D 点对应关系中寻找物体姿态 \( {}^{c}\mathbf{T}_o \)。
 
bool cv::solvePnP (InputArray objectPoints, InputArray imagePoints, InputArray cameraMatrix, InputArray distCoeffs, OutputArray rvec, OutputArray tvec, bool useExtrinsicGuess=false, int flags=SOLVEPNP_ITERATIVE)
 从 3D-2D 点对应关系中寻找物体姿态 \( {}^{c}\mathbf{T}_o \)
 
int cv::solvePnPGeneric (InputArray objectPoints, InputArray imagePoints, InputArray cameraMatrix, InputArray distCoeffs, OutputArrayOfArrays rvecs, OutputArrayOfArrays tvecs, bool useExtrinsicGuess=false, SolvePnPMethod flags=SOLVEPNP_ITERATIVE, InputArray rvec=noArray(), InputArray tvec=noArray(), OutputArray reprojectionError=noArray())
 从 3D-2D 点对应关系中寻找物体姿态 \( {}^{c}\mathbf{T}_o \)。
 
bool cv::solvePnPRansac (InputArray objectPoints, InputArray imagePoints, InputArray cameraMatrix, InputArray distCoeffs, OutputArray rvec, OutputArray tvec, bool useExtrinsicGuess=false, int iterationsCount=100, float reprojectionError=8.0, double confidence=0.99, OutputArray inliers=noArray(), int flags=SOLVEPNP_ITERATIVE)
 利用 RANSAC 方案从 3D-2D 点对应关系中寻找物体姿态 \( {}^{c}\mathbf{T}_o \),以处理错误匹配。
 
bool cv::solvePnPRansac (InputArray objectPoints, InputArray imagePoints, InputOutputArray cameraMatrix, InputArray distCoeffs, OutputArray rvec, OutputArray tvec, OutputArray inliers, const UsacParams &params=UsacParams())
 
void cv::solvePnPRefineLM (InputArray objectPoints, InputArray imagePoints, InputArray cameraMatrix, InputArray distCoeffs, InputOutputArray rvec, InputOutputArray tvec, TermCriteria criteria=TermCriteria(TermCriteria::EPS+TermCriteria::COUNT, 20, FLT_EPSILON))
 基于 3D-2D 点对应关系,从初始解开始精细化姿态(将物体坐标系中的 3D 点变换到相机坐标系的平移和旋转向量)。
 
void cv::solvePnPRefineVVS (InputArray objectPoints, InputArray imagePoints, InputArray cameraMatrix, InputArray distCoeffs, InputOutputArray rvec, InputOutputArray tvec, TermCriteria criteria=TermCriteria(TermCriteria::EPS+TermCriteria::COUNT, 20, FLT_EPSILON), double VVSlambda=1)
 基于 3D-2D 点对应关系,从初始解开始精细化姿态(将物体坐标系中的 3D 点变换到相机坐标系的平移和旋转向量)。
 
double cv::stereoCalibrate (InputArrayOfArrays objectPoints, InputArrayOfArrays imagePoints1, InputArrayOfArrays imagePoints2, InputOutputArray cameraMatrix1, InputOutputArray distCoeffs1, InputOutputArray cameraMatrix2, InputOutputArray distCoeffs2, Size imageSize, InputOutputArray R, InputOutputArray T, OutputArray E, OutputArray F, OutputArray perViewErrors, int flags=CALIB_FIX_INTRINSIC, TermCriteria criteria=TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, 1e-6))
 这是一个重载的成员函数,为方便起见而提供。它与上述函数的区别仅在于所接受的参数不同。
 
double cv::stereoCalibrate (InputArrayOfArrays objectPoints, InputArrayOfArrays imagePoints1, InputArrayOfArrays imagePoints2, InputOutputArray cameraMatrix1, InputOutputArray distCoeffs1, InputOutputArray cameraMatrix2, InputOutputArray distCoeffs2, Size imageSize, InputOutputArray R, InputOutputArray T, OutputArray E, OutputArray F, OutputArrayOfArrays rvecs, OutputArrayOfArrays tvecs, OutputArray perViewErrors, int flags=CALIB_FIX_INTRINSIC, TermCriteria criteria=TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, 1e-6))
 标定双目相机设置。此函数计算两个相机各自的内参数,以及两个相机之间的外参数。
 
double cv::stereoCalibrate (InputArrayOfArrays objectPoints, InputArrayOfArrays imagePoints1, InputArrayOfArrays imagePoints2, InputOutputArray cameraMatrix1, InputOutputArray distCoeffs1, InputOutputArray cameraMatrix2, InputOutputArray distCoeffs2, Size imageSize, OutputArray R, OutputArray T, OutputArray E, OutputArray F, int flags=CALIB_FIX_INTRINSIC, TermCriteria criteria=TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, 1e-6))
 这是一个重载的成员函数,为方便起见而提供。它与上述函数的区别仅在于所接受的参数不同。
 
void cv::stereoRectify (InputArray cameraMatrix1, InputArray distCoeffs1, InputArray cameraMatrix2, InputArray distCoeffs2, Size imageSize, InputArray R, InputArray T, OutputArray R1, OutputArray R2, OutputArray P1, OutputArray P2, OutputArray Q, int flags=CALIB_ZERO_DISPARITY, double alpha=-1, Size newImageSize=Size(), Rect *validPixROI1=0, Rect *validPixROI2=0)
 为已标定的立体相机的每个镜头计算校正变换。
 
bool cv::stereoRectifyUncalibrated (InputArray points1, InputArray points2, InputArray F, Size imgSize, OutputArray H1, OutputArray H2, double threshold=5)
 为未标定的立体相机计算校正变换。
 
void cv::triangulatePoints (InputArray projMatr1, InputArray projMatr2, InputArray projPoints1, InputArray projPoints2, OutputArray points4D)
 此函数利用立体相机的观测结果重建三维点(齐次坐标)。
 
void cv::undistort (InputArray src, OutputArray dst, InputArray cameraMatrix, InputArray distCoeffs, InputArray newCameraMatrix=noArray())
 对图像进行变换以补偿镜头畸变。
 
void cv::undistortImagePoints (InputArray src, OutputArray dst, InputArray cameraMatrix, InputArray distCoeffs, TermCriteria=TermCriteria(TermCriteria::MAX_ITER, 5, 0.01))
 计算去畸变后的图像点位置。
 
void cv::undistortPoints (InputArray src, OutputArray dst, InputArray cameraMatrix, InputArray distCoeffs, InputArray R, InputArray P, TermCriteria criteria)
 
void cv::undistortPoints (InputArray src, OutputArray dst, InputArray cameraMatrix, InputArray distCoeffs, InputArray R=noArray(), InputArray P=noArray())
 根据观测到的点坐标计算理想点坐标。
 
void cv::validateDisparity (InputOutputArray disparity, InputArray cost, int minDisparity, int numberOfDisparities, int disp12MaxDisp=1)
 使用左右检查(left-right check)验证视差。矩阵“cost”应由双目匹配算法计算得出。
 

类型定义文档 (Typedef Documentation)

◆ CirclesGridFinderParameters2

枚举类型文档 (Enumeration Type Documentation)

◆ anonymous enum

匿名枚举

#include <opencv2/calib3d.hpp>

鲁棒估计算法类型

枚举值 (Enumerator)
LMEDS 
Python: cv.LMEDS

最小中值平方算法

RANSAC 
Python: cv.RANSAC

RANSAC算法。

RHO 
Python: cv.RHO

RHO算法。

USAC_DEFAULT 
Python: cv.USAC_DEFAULT

USAC算法,默认设置。

USAC_PARALLEL 
Python: cv.USAC_PARALLEL

USAC,并行版本。

USAC_FM_8PTS 
Python: cv.USAC_FM_8PTS

USAC,基础矩阵8点法。

USAC_FAST 
Python: cv.USAC_FAST

USAC,快速设置。

USAC_ACCURATE 
Python: cv.USAC_ACCURATE

USAC,精确设置。

USAC_PROSAC 
Python: cv.USAC_PROSAC

USAC,排序点,运行PROSAC。

USAC_MAGSAC 
Python: cv.USAC_MAGSAC

USAC,运行MAGSAC++。

◆ anonymous enum

匿名枚举

#include <opencv2/calib3d.hpp>

枚举值 (Enumerator)
CALIB_CB_ADAPTIVE_THRESH 
Python: cv.CALIB_CB_ADAPTIVE_THRESH
CALIB_CB_NORMALIZE_IMAGE 
Python: cv.CALIB_CB_NORMALIZE_IMAGE
CALIB_CB_FILTER_QUADS 
Python: cv.CALIB_CB_FILTER_QUADS
CALIB_CB_FAST_CHECK 
Python: cv.CALIB_CB_FAST_CHECK
CALIB_CB_EXHAUSTIVE 
Python: cv.CALIB_CB_EXHAUSTIVE
CALIB_CB_ACCURACY 
Python: cv.CALIB_CB_ACCURACY
CALIB_CB_LARGER 
Python: cv.CALIB_CB_LARGER
CALIB_CB_MARKER 
Python: cv.CALIB_CB_MARKER
CALIB_CB_PLAIN 
Python: cv.CALIB_CB_PLAIN

◆ anonymous enum

匿名枚举

#include <opencv2/calib3d.hpp>

枚举值 (Enumerator)
CALIB_CB_SYMMETRIC_GRID 
Python: cv.CALIB_CB_SYMMETRIC_GRID
CALIB_CB_ASYMMETRIC_GRID 
Python: cv.CALIB_CB_ASYMMETRIC_GRID
CALIB_CB_CLUSTERING 
Python: cv.CALIB_CB_CLUSTERING

◆ anonymous enum

匿名枚举

#include <opencv2/calib3d.hpp>

枚举值 (Enumerator)
CALIB_NINTRINSIC 
Python: cv.CALIB_NINTRINSIC
CALIB_USE_INTRINSIC_GUESS 
Python: cv.CALIB_USE_INTRINSIC_GUESS
CALIB_FIX_ASPECT_RATIO 
Python: cv.CALIB_FIX_ASPECT_RATIO
CALIB_FIX_PRINCIPAL_POINT 
Python: cv.CALIB_FIX_PRINCIPAL_POINT
CALIB_ZERO_TANGENT_DIST 
Python: cv.CALIB_ZERO_TANGENT_DIST
CALIB_FIX_FOCAL_LENGTH 
Python: cv.CALIB_FIX_FOCAL_LENGTH
CALIB_FIX_K1 
Python: cv.CALIB_FIX_K1
CALIB_FIX_K2 
Python: cv.CALIB_FIX_K2
CALIB_FIX_K3 
Python: cv.CALIB_FIX_K3
CALIB_FIX_K4 
Python: cv.CALIB_FIX_K4
CALIB_FIX_K5 
Python: cv.CALIB_FIX_K5
CALIB_FIX_K6 
Python: cv.CALIB_FIX_K6
CALIB_RATIONAL_MODEL 
Python: cv.CALIB_RATIONAL_MODEL
CALIB_THIN_PRISM_MODEL 
Python: cv.CALIB_THIN_PRISM_MODEL
CALIB_FIX_S1_S2_S3_S4 
Python: cv.CALIB_FIX_S1_S2_S3_S4
CALIB_TILTED_MODEL 
Python: cv.CALIB_TILTED_MODEL
CALIB_FIX_TAUX_TAUY 
Python: cv.CALIB_FIX_TAUX_TAUY
CALIB_USE_QR 
Python: cv.CALIB_USE_QR

使用QR而非SVD分解进行求解。速度更快但可能精度较低

CALIB_FIX_TANGENT_DIST 
Python: cv.CALIB_FIX_TANGENT_DIST
CALIB_FIX_INTRINSIC 
Python: cv.CALIB_FIX_INTRINSIC
CALIB_SAME_FOCAL_LENGTH 
Python: cv.CALIB_SAME_FOCAL_LENGTH
CALIB_ZERO_DISPARITY 
Python: cv.CALIB_ZERO_DISPARITY
CALIB_USE_LU 
Python: cv.CALIB_USE_LU

使用LU而非SVD分解进行求解。速度快得多但可能精度较低

CALIB_USE_EXTRINSIC_GUESS 
Python: cv.CALIB_USE_EXTRINSIC_GUESS

用于stereoCalibrate

◆ anonymous enum

匿名枚举

#include <opencv2/calib3d.hpp>

用于寻找基础矩阵的算法

枚举值 (Enumerator)
FM_7POINT 
Python: cv.FM_7POINT

7点算法

FM_8POINT 
Python: cv.FM_8POINT

8点算法

FM_LMEDS 
Python: cv.FM_LMEDS

最小中值算法。使用7点算法。

FM_RANSAC 
Python: cv.FM_RANSAC

RANSAC算法。至少需要15个点。使用7点算法。

◆ HandEyeCalibrationMethod

#include <opencv2/calib3d.hpp>

枚举值 (Enumerator)
CALIB_HAND_EYE_TSAI 
Python: cv.CALIB_HAND_EYE_TSAI

一种新的全自动高效3D机器人手眼标定技术 [280]

CALIB_HAND_EYE_PARK 
Python: cv.CALIB_HAND_EYE_PARK

机器人传感器标定:在欧几里得群上求解 AX = XB [219]

CALIB_HAND_EYE_HORAUD 
Python: cv.CALIB_HAND_EYE_HORAUD

手眼标定 [130]

CALIB_HAND_EYE_ANDREFF 
Python: cv.CALIB_HAND_EYE_ANDREFF

在线手眼标定 [14]

CALIB_HAND_EYE_DANIILIDIS 
Python: cv.CALIB_HAND_EYE_DANIILIDIS

使用双四元数进行手眼标定 [68]

◆ LocalOptimMethod

#include <opencv2/calib3d.hpp>

枚举值 (Enumerator)
LOCAL_OPTIM_NULL 
Python: cv.LOCAL_OPTIM_NULL
LOCAL_OPTIM_INNER_LO 
Python: cv.LOCAL_OPTIM_INNER_LO
LOCAL_OPTIM_INNER_AND_ITER_LO 
Python: cv.LOCAL_OPTIM_INNER_AND_ITER_LO
LOCAL_OPTIM_GC 
Python: cv.LOCAL_OPTIM_GC
LOCAL_OPTIM_SIGMA 
Python: cv.LOCAL_OPTIM_SIGMA

◆ NeighborSearchMethod

#include <opencv2/calib3d.hpp>

枚举值 (Enumerator)
NEIGH_FLANN_KNN 
Python: cv.NEIGH_FLANN_KNN
NEIGH_GRID 
Python: cv.NEIGH_GRID
NEIGH_FLANN_RADIUS 
Python: cv.NEIGH_FLANN_RADIUS

◆ PolishingMethod

#include <opencv2/calib3d.hpp>

枚举值 (Enumerator)
NONE_POLISHER 
Python: cv.NONE_POLISHER
LSQ_POLISHER 
Python: cv.LSQ_POLISHER
MAGSAC 
Python: cv.MAGSAC
COV_POLISHER 
Python: cv.COV_POLISHER

◆ RobotWorldHandEyeCalibrationMethod

#include <opencv2/calib3d.hpp>

枚举值 (Enumerator)
CALIB_ROBOT_WORLD_HAND_EYE_SHAH 
Python: cv.CALIB_ROBOT_WORLD_HAND_EYE_SHAH

使用克罗内克积求解机器人-世界/手眼标定问题 [250]

CALIB_ROBOT_WORLD_HAND_EYE_LI 
Python: cv.CALIB_ROBOT_WORLD_HAND_EYE_LI

使用双四元数和克罗内克积同时进行机器人-世界和手眼标定 [168]

◆ SamplingMethod

#include <opencv2/calib3d.hpp>

枚举值 (Enumerator)
SAMPLING_UNIFORM 
Python: cv.SAMPLING_UNIFORM
SAMPLING_PROGRESSIVE_NAPSAC 
Python: cv.SAMPLING_PROGRESSIVE_NAPSAC
SAMPLING_NAPSAC 
Python: cv.SAMPLING_NAPSAC
SAMPLING_PROSAC 
Python: cv.SAMPLING_PROSAC

◆ ScoreMethod

#include <opencv2/calib3d.hpp>

枚举值 (Enumerator)
SCORE_METHOD_RANSAC 
Python: cv.SCORE_METHOD_RANSAC
SCORE_METHOD_MSAC 
Python: cv.SCORE_METHOD_MSAC
SCORE_METHOD_MAGSAC 
Python: cv.SCORE_METHOD_MAGSAC
SCORE_METHOD_LMEDS 
Python: cv.SCORE_METHOD_LMEDS

◆ SolvePnPMethod

#include <opencv2/calib3d.hpp>

枚举值 (Enumerator)
SOLVEPNP_ITERATIVE 
Python: cv.SOLVEPNP_ITERATIVE

使用非线性Levenberg-Marquardt最小化方案进行姿态优化 [184] [81]
非平面"objectPoints"的初始解需要至少6个点,并使用DLT算法。
平面"objectPoints"的初始解需要至少4个点,并使用单应性分解的姿态。

SOLVEPNP_EPNP 
Python: cv.SOLVEPNP_EPNP

EPnP:高效的透视n点相机姿态估计 [163]

SOLVEPNP_P3P 
Python: cv.SOLVEPNP_P3P

P3P问题再探 [73]

SOLVEPNP_DLS 
Python: cv.SOLVEPNP_DLS

实现已损坏。使用此标志将回退到EPnP。
PnP的直接最小二乘(DLS)方法 [128]

SOLVEPNP_UPNP 
Python: cv.SOLVEPNP_UPNP

实现已损坏。使用此标志将回退到EPnP。
用于鲁棒相机姿态和焦距估计的穷举线性化 [220]

SOLVEPNP_AP3P 
Python: cv.SOLVEPNP_AP3P

透视三点问题的有效代数解 [150]

SOLVEPNP_IPPE 
Python: cv.SOLVEPNP_IPPE

基于无穷小平面的姿态估计 [64]
目标点必须共面。

SOLVEPNP_IPPE_SQUARE 
Python: cv.SOLVEPNP_IPPE_SQUARE

基于无穷小平面的姿态估计 [64]
这是适用于标记姿态估计的特殊情况。
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]
SOLVEPNP_SQPNP 
Python: cv.SOLVEPNP_SQPNP

SQPnP:透视n点问题的持续快速且全局最优解 [274]

◆ UndistortTypes

#include <opencv2/calib3d.hpp>

cv::undistort 模式

枚举值 (Enumerator)
PROJ_SPHERICAL_ORTHO 
Python: cv.PROJ_SPHERICAL_ORTHO
PROJ_SPHERICAL_EQRECT 
Python: cv.PROJ_SPHERICAL_EQRECT

函数文档 (Function Documentation)

◆ calibrateCamera() [1/2]

double cv::calibrateCamera ( InputArrayOfArrays objectPoints,
InputArrayOfArrays imagePoints,
Size imageSize,
InputOutputArray cameraMatrix,
InputOutputArray distCoeffs,
OutputArrayOfArrays rvecs,
OutputArrayOfArrays tvecs,
int flags = 0,
TermCriteria criteria = TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, DBL_EPSILON) )
Python
cv.calibrateCamera(objectPoints, imagePoints, imageSize, cameraMatrix, distCoeffs[, rvecs[, tvecs[, flags[, criteria]]]]) -> retval, cameraMatrix, distCoeffs, rvecs, tvecs
cv.calibrateCameraExtended(objectPoints, imagePoints, imageSize, cameraMatrix, distCoeffs[, rvecs[, tvecs[, stdDeviationsIntrinsics[, stdDeviationsExtrinsics[, perViewErrors[, flags[, criteria]]]]]]]) -> retval, cameraMatrix, distCoeffs, rvecs, tvecs, stdDeviationsIntrinsics, stdDeviationsExtrinsics, perViewErrors

#include <opencv2/calib3d.hpp>

这是一个重载的成员函数,为方便起见而提供。它与上述函数的区别仅在于所接受的参数不同。

◆ calibrateCamera() [2/2]

double cv::calibrateCamera ( InputArrayOfArrays objectPoints,
InputArrayOfArrays imagePoints,
Size imageSize,
InputOutputArray cameraMatrix,
InputOutputArray distCoeffs,
OutputArrayOfArrays rvecs,
OutputArrayOfArrays tvecs,
OutputArray stdDeviationsIntrinsics,
OutputArray stdDeviationsExtrinsics,
OutputArray perViewErrors,
int flags = 0,
TermCriteria criteria = TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, DBL_EPSILON) )
Python
cv.calibrateCamera(objectPoints, imagePoints, imageSize, cameraMatrix, distCoeffs[, rvecs[, tvecs[, flags[, criteria]]]]) -> retval, cameraMatrix, distCoeffs, rvecs, tvecs
cv.calibrateCameraExtended(objectPoints, imagePoints, imageSize, cameraMatrix, distCoeffs[, rvecs[, tvecs[, stdDeviationsIntrinsics[, stdDeviationsExtrinsics[, perViewErrors[, flags[, criteria]]]]]]]) -> retval, cameraMatrix, distCoeffs, rvecs, tvecs, stdDeviationsIntrinsics, stdDeviationsExtrinsics, perViewErrors

#include <opencv2/calib3d.hpp>

从标定图案的多个视图中寻找相机内参和外参参数。

参数
objectPoints在新接口中,它是校准模式坐标空间中校准模式点的向量的向量(例如 std::vector<std::vector<cv::Vec3f>>)。外部向量包含的元素数量与模式视图数量相同。如果每个视图都显示相同的校准模式并且完全可见,则所有向量都将相同。但是,也可以在不同的视图中使用部分遮挡的模式甚至不同的模式。然后,向量将不同。尽管这些点是3D的,但如果使用的校准模式是平面装置,它们都位于校准模式的XY坐标平面(因此Z坐标为0)。只要提供初始cameraMatrix,也可以使用3D校准装置。
imagePoints在新接口中,它是校准模式点投影的向量的向量(例如 std::vector<std::vector<cv::Vec2f>>)。imagePoints.size() 和 objectPoints.size(),以及每个 i 的 imagePoints[i].size() 和 objectPoints[i].size() 必须分别相等。在旧接口中,来自不同视图的所有对象点向量被连接在一起。
imageSize仅用于初始化相机内参矩阵的图像尺寸。
cameraMatrix输入/输出 3x3 浮点相机内参矩阵 \(\cameramatrix{A}\) 。如果指定了 CALIB_USE_INTRINSIC_GUESS 和/或 CALIB_FIX_ASPECT_RATIOCALIB_FIX_PRINCIPAL_POINTCALIB_FIX_FOCAL_LENGTH,则在调用函数之前必须初始化 fx、fy、cx、cy 中的部分或全部。
distCoeffs输入/输出 畸变系数向量 \(\distcoeffs\)。
rvecs为每个模式视图估计的旋转向量(Rodrigues)输出向量(例如 std::vector<cv::Mat>>)。也就是说,每个第 i 个旋转向量与相应的第 i 个平移向量(参见下一个输出参数描述)将校准模式从对象坐标空间(其中指定了对象点)带到相机坐标空间。更具体地说,第 i 个旋转向量和平移向量的元组执行从对象坐标空间到相机坐标空间的基变换。由于其对偶性,此元组等同于校准模式相对于相机坐标空间的位置。
tvecs为每个模式视图估计的平移向量输出向量,参见上面的参数描述。
stdDeviationsIntrinsics内参估计的标准偏差输出向量。偏差值顺序: \((f_x, f_y, c_x, c_y, k_1, k_2, p_1, p_2, k_3, k_4, k_5, k_6 , s_1, s_2, s_3, s_4, \tau_x, \tau_y)\) 如果其中一个参数未估计,则其偏差等于零。
stdDeviationsExtrinsics外参估计的标准偏差输出向量。偏差值顺序: \((R_0, T_0, \dotsc , R_{M - 1}, T_{M - 1})\),其中 M 是模式视图的数量。 \(R_i, T_i\) 是连接的 1x3 向量。
perViewErrors为每个模式视图估计的RMS重投影误差输出向量。
flags (标志)可以是零或以下值的组合的不同标志
  • CALIB_USE_INTRINSIC_GUESS cameraMatrix 包含 fx, fy, cx, cy 的有效初始值,这些值将进一步优化。否则,(cx, cy) 最初设置为图像中心(使用 imageSize),焦距以最小二乘法计算。请注意,如果内参已知,则无需使用此函数来估计外参。请改用 solvePnP
  • CALIB_FIX_PRINCIPAL_POINT 在全局优化期间,主点不改变。它保持在中心或在设置 CALIB_USE_INTRINSIC_GUESS 时指定的不同位置。
  • CALIB_FIX_ASPECT_RATIO 函数只将 fy 视为自由参数。fx/fy 的比率与输入 cameraMatrix 中的比率保持相同。当未设置 CALIB_USE_INTRINSIC_GUESS 时,fx 和 fy 的实际输入值被忽略,只计算并使用它们的比率。
  • CALIB_ZERO_TANGENT_DIST 切向畸变系数 \((p_1, p_2)\) 设置为零并保持为零。
  • CALIB_FIX_FOCAL_LENGTH 如果设置了 CALIB_USE_INTRINSIC_GUESS,则在全局优化期间焦距不改变。
  • CALIB_FIX_K1,..., CALIB_FIX_K6 在优化期间不改变相应的径向畸变系数。如果设置了 CALIB_USE_INTRINSIC_GUESS,则使用提供的 distCoeffs 矩阵中的系数。否则,将其设置为 0。
  • CALIB_RATIONAL_MODEL 启用系数 k4、k5 和 k6。为了提供向后兼容性,应明确指定此额外标志,以使校准函数使用有理模型并返回8个或更多系数。
  • CALIB_THIN_PRISM_MODEL 启用系数 s1、s2、s3 和 s4。为了提供向后兼容性,应明确指定此额外标志,以使校准函数使用薄棱镜模型并返回12个或更多系数。
  • CALIB_FIX_S1_S2_S3_S4 在优化期间不改变薄棱镜畸变系数。如果设置了 CALIB_USE_INTRINSIC_GUESS,则使用提供的 distCoeffs 矩阵中的系数。否则,将其设置为 0。
  • CALIB_TILTED_MODEL 启用系数 tauX 和 tauY。为了提供向后兼容性,应明确指定此额外标志,以使校准函数使用倾斜传感器模型并返回14个系数。
  • CALIB_FIX_TAUX_TAUY 在优化期间不改变倾斜传感器模型的系数。如果设置了 CALIB_USE_INTRINSIC_GUESS,则使用提供的 distCoeffs 矩阵中的系数。否则,将其设置为 0。
criteria迭代优化算法的终止条件。
返回
总体RMS重投影误差。

该函数估计相机的内参和每个视图的外参。该算法基于 [324][39]。必须指定3D对象点的坐标及其在每个视图中对应的2D投影。这可以通过使用具有已知几何形状和易于检测特征点的对象来实现。这样的对象称为校准装置或校准图案,OpenCV内置支持棋盘作为校准装置(参见 findChessboardCorners)。目前,内参的初始化(当未设置 CALIB_USE_INTRINSIC_GUESS 时)仅适用于平面校准图案(其中对象点的Z坐标必须都为零)。只要提供初始cameraMatrix,也可以使用3D校准装置。

该算法执行以下步骤

  • 计算初始内参(仅适用于平面校准图案的选项)或从输入参数中读取它们。除非指定了某些 CALIB_FIX_K?,否则畸变系数最初都设置为零。
  • 估计初始相机姿态,如同内参已经已知一样。这是使用 solvePnP 完成的。
  • 运行全局Levenberg-Marquardt优化算法,以最小化重投影误差,即观察到的特征点 imagePoints 和投影的(使用当前相机参数和姿态估计)对象点 objectPoints 之间距离的平方和。有关详细信息,请参阅 projectPoints
注意
如果您使用非方形(即非 N-by-N)网格和 findChessboardCorners 进行校准,并且 calibrateCamera 返回不好的值(零畸变系数、\(c_x\) 和 \(c_y\) 离图像中心很远,和/或 \(f_x\) 和 \(f_y\) 之间差异很大(比例为 10:1 或更大)),那么您可能在 findChessboardCorners 中使用了 patternSize=cvSize(rows,cols) 而不是 patternSize=cvSize(cols,rows)。
如果提供不支持的参数组合或系统受约束不足,该函数可能会抛出异常。
另请参阅
calibrateCameraRO, findChessboardCorners, solvePnP, initCameraMatrix2D, stereoCalibrate, undistort

◆ calibrateCameraRO() [1/2]

double cv::calibrateCameraRO ( InputArrayOfArrays objectPoints,
InputArrayOfArrays imagePoints,
Size imageSize,
int iFixedPoint,
InputOutputArray cameraMatrix,
InputOutputArray distCoeffs,
OutputArrayOfArrays rvecs,
OutputArrayOfArrays tvecs,
OutputArray newObjPoints,
int flags = 0,
TermCriteria criteria = TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, DBL_EPSILON) )
Python
cv.calibrateCameraRO(objectPoints, imagePoints, imageSize, iFixedPoint, cameraMatrix, distCoeffs[, rvecs[, tvecs[, newObjPoints[, flags[, criteria]]]]]) -> retval, cameraMatrix, distCoeffs, rvecs, tvecs, newObjPoints
cv.calibrateCameraROExtended(objectPoints, imagePoints, imageSize, iFixedPoint, cameraMatrix, distCoeffs[, rvecs[, tvecs[, newObjPoints[, stdDeviationsIntrinsics[, stdDeviationsExtrinsics[, stdDeviationsObjPoints[, perViewErrors[, flags[, criteria]]]]]]]]]) -> retval, cameraMatrix, distCoeffs, rvecs, tvecs, newObjPoints, stdDeviationsIntrinsics, stdDeviationsExtrinsics, stdDeviationsObjPoints, perViewErrors

#include <opencv2/calib3d.hpp>

这是一个重载的成员函数,为方便起见而提供。它与上述函数的区别仅在于所接受的参数不同。

◆ calibrateCameraRO() [2/2]

double cv::calibrateCameraRO ( InputArrayOfArrays objectPoints,
InputArrayOfArrays imagePoints,
Size imageSize,
int iFixedPoint,
InputOutputArray cameraMatrix,
InputOutputArray distCoeffs,
OutputArrayOfArrays rvecs,
OutputArrayOfArrays tvecs,
OutputArray newObjPoints,
OutputArray stdDeviationsIntrinsics,
OutputArray stdDeviationsExtrinsics,
OutputArray stdDeviationsObjPoints,
OutputArray perViewErrors,
int flags = 0,
TermCriteria criteria = TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, DBL_EPSILON) )
Python
cv.calibrateCameraRO(objectPoints, imagePoints, imageSize, iFixedPoint, cameraMatrix, distCoeffs[, rvecs[, tvecs[, newObjPoints[, flags[, criteria]]]]]) -> retval, cameraMatrix, distCoeffs, rvecs, tvecs, newObjPoints
cv.calibrateCameraROExtended(objectPoints, imagePoints, imageSize, iFixedPoint, cameraMatrix, distCoeffs[, rvecs[, tvecs[, newObjPoints[, stdDeviationsIntrinsics[, stdDeviationsExtrinsics[, stdDeviationsObjPoints[, perViewErrors[, flags[, criteria]]]]]]]]]) -> retval, cameraMatrix, distCoeffs, rvecs, tvecs, newObjPoints, stdDeviationsIntrinsics, stdDeviationsExtrinsics, stdDeviationsObjPoints, perViewErrors

#include <opencv2/calib3d.hpp>

从标定图案的多个视图中寻找相机内参和外参参数。

此函数是 calibrateCamera 的扩展,采用了 [261] 中提出的释放对象方法。在许多常见的不准确、未测量、大致平面的目标(校准板)情况下,此方法可以显著提高估计相机参数的精度。此函数支持对象释放方法和标准方法。使用参数 iFixedPoint 进行方法选择。在内部实现中,calibrateCamera 是此函数的包装器。

参数
objectPoints校准图案坐标空间中校准图案点的向量的向量。详见 calibrateCamera。如果使用对象释放方法,每个视图中必须使用相同的校准板,并且必须完全可见,并且所有 objectPoints[i] 必须相同,并且所有点应大致接近一个平面。校准目标必须是刚性的,或者至少在相机(而非校准目标)移动以抓取图像时是静态的。
imagePoints校准图案点投影的向量的向量。详见 calibrateCamera
imageSize仅用于初始化相机内参矩阵的图像尺寸。
iFixedPoint要固定的 objectPoints[0] 中 3D 对象点的索引。它也作为校准方法选择的开关。如果使用对象释放方法,则传入参数的范围为 [1, objectPoints[0].size()-2],否则超出此范围的值将选择标准校准方法。通常,当使用对象释放方法时,建议固定校准板网格的右上角点。根据 [261],还有另外两个点也被固定。在此实现中,使用了 objectPoints[0].front 和 objectPoints[0].back.z。使用对象释放方法时,只有当这三个固定点的坐标足够准确时,才能获得准确的 rvecs、tvecs 和 newObjPoints。如果不需要,可以传入 noArray()。标准校准方法会忽略此参数。
cameraMatrix输出 3x3 浮点相机矩阵。详见 calibrateCamera
distCoeffs畸变系数输出向量。详见 calibrateCamera
rvecs为每个模式视图估计的旋转向量输出向量。详见 calibrateCamera
tvecs为每个模式视图估计的平移向量输出向量。
newObjPoints校准图案点更新后的输出向量。坐标可能会根据三个固定点进行缩放。只有当上述三个固定点准确时,返回的坐标才准确。如果不需要,可以传入 noArray()。标准校准方法会忽略此参数。
stdDeviationsIntrinsics内参估计的标准偏差输出向量。详见 calibrateCamera
stdDeviationsExtrinsics外参估计的标准偏差输出向量。详见 calibrateCamera
stdDeviationsObjPoints精炼后的校准图案点坐标的标准偏差输出向量。它与 objectPoints[0] 向量具有相同的大小和顺序。标准校准方法会忽略此参数。
perViewErrors为每个模式视图估计的RMS重投影误差输出向量。
flags (标志)可以是零或一些预定义值的组合的不同标志。有关详细信息,请参阅 calibrateCamera。如果使用对象释放方法,校准时间可能会更长。CALIB_USE_QR 或 CALIB_USE_LU 可用于更快校准,但在某些罕见情况下可能会精度较低且稳定性较差。
criteria迭代优化算法的终止条件。
返回
总体RMS重投影误差。

该函数估计相机的内参和每个视图的外参。该算法基于 [324], [39][261]。有关其他详细解释,请参阅 calibrateCamera

另请参阅
calibrateCamera, findChessboardCorners, solvePnP, initCameraMatrix2D, stereoCalibrate, undistort

◆ calibrateHandEye()

void cv::calibrateHandEye ( InputArrayOfArrays R_gripper2base,
InputArrayOfArrays t_gripper2base,
InputArrayOfArrays R_target2cam,
InputArrayOfArrays t_target2cam,
OutputArray R_cam2gripper,
OutputArray t_cam2gripper,
HandEyeCalibrationMethod method = CALIB_HAND_EYE_TSAI )
Python
cv.calibrateHandEye(R_gripper2base, t_gripper2base, R_target2cam, t_target2cam[, R_cam2gripper[, t_cam2gripper[, method]]]) -> R_cam2gripper, t_cam2gripper

#include <opencv2/calib3d.hpp>

计算手眼标定:\(_{}^{g}\textrm{T}_c\)。

参数
[in]R_gripper2base从将夹持器框架中表示的点变换到机器人基座框架中的齐次矩阵中提取的旋转部分( \(_{}^{b}\textrm{T}_g\))。这是一个向量(vector<Mat>),其中包含从夹持器框架到机器人基座框架的所有变换的旋转(3x3旋转矩阵或3x1旋转向量)。
[in]t_gripper2base从将夹持器框架中表示的点变换到机器人基座框架中的齐次矩阵中提取的平移部分( \(_{}^{b}\textrm{T}_g\))。这是一个向量(vector<Mat>),其中包含从夹持器框架到机器人基座框架的所有变换的3x1平移向量。
[in]R_target2cam从将目标框架中表示的点变换到相机框架中的齐次矩阵中提取的旋转部分( \(_{}^{c}\textrm{T}_t\))。这是一个向量(vector<Mat>),其中包含从校准目标框架到相机框架的所有变换的旋转(3x3旋转矩阵或3x1旋转向量)。
[in]t_target2cam从将目标框架中表示的点变换到相机框架中的齐次矩阵中提取的旋转部分( \(_{}^{c}\textrm{T}_t\))。这是一个向量(vector<Mat>),其中包含从校准目标框架到相机框架的所有变换的3x1平移向量。
[out]R_cam2gripper从将相机框架中表示的点变换到夹持器框架中的齐次矩阵中提取的估计 (3x3) 旋转部分( \(_{}^{g}\textrm{T}_c\))。
[out]t_cam2gripper从将相机框架中表示的点变换到夹持器框架中的齐次矩阵中提取的估计 (3x1) 平移部分( \(_{}^{g}\textrm{T}_c\))。
[in]method其中一种已实现的手眼标定方法,参见 cv::HandEyeCalibrationMethod

该函数使用各种方法执行手眼标定。一种方法是先估计旋转,然后估计平移(可分离解),并实现了以下方法:

  • R. Tsai, R. Lenz 一种用于全自主高效3D机器人手眼标定新技术 [280]
  • F. Park, B. Martin 机器人传感器标定:在欧几里得群上求解 AX = XB [219]
  • R. Horaud, F. Dornaika 手眼标定 [130]

另一种方法是同时估计旋转和平移(同时解),并实现了以下方法:

  • N. Andreff, R. Horaud, B. Espiau 在线手眼标定 [14]
  • K. Daniilidis 使用对偶四元数进行手眼标定 [68]

下图描述了手眼标定问题,其中必须估计安装在机器人夹具(“手”)上的相机(“眼”)之间的变换。这种配置称为手持式。

眼对手配置包括一个静态相机观察安装在机器人末端执行器上的校准图案。然后可以通过将合适的变换输入函数来估计从相机到机器人基座框架的变换,如下所示。

标定过程如下:

  • 使用静态校准图案来估计目标框架与相机框架之间的变换
  • 移动机器人夹持器以获取多个姿态
  • 对于每个姿态,使用机器人运动学记录夹持器框架和机器人基座框架之间的齐次变换

    \[ \begin{bmatrix} X_b\\ Y_b\\ Z_b\\ 1 \end{bmatrix} = \begin{bmatrix} _{}^{b}\textrm{R}_g & _{}^{b}\textrm{t}_g \\ 0_{1 \times 3} & 1 \end{bmatrix} \begin{bmatrix} X_g\\ Y_g\\ Z_g\\ 1 \end{bmatrix} \]

  • 对于每个姿态,使用例如基于2D-3D点对应关系的姿态估计方法(PnP)记录校准目标框架与相机框架之间的齐次变换

    \[ \begin{bmatrix} X_c\\ Y_c\\ Z_c\\ 1 \end{bmatrix} = \begin{bmatrix} _{}^{c}\textrm{R}_t & _{}^{c}\textrm{t}_t \\ 0_{1 \times 3} & 1 \end{bmatrix} \begin{bmatrix} X_t\\ Y_t\\ Z_t\\ 1 \end{bmatrix} \]

手眼标定程序返回以下齐次变换

\[ \begin{bmatrix} X_g\\ Y_g\\ Z_g\\ 1 \end{bmatrix} = \begin{bmatrix} _{}^{g}\textrm{R}_c & _{}^{g}\textrm{t}_c \\ 0_{1 \times 3} & 1 \end{bmatrix} \begin{bmatrix} X_c\\ Y_c\\ Z_c\\ 1 \end{bmatrix} \]

此问题也称为求解 \(\mathbf{A}\mathbf{X}=\mathbf{X}\mathbf{B}\) 方程

  • 用于手持式配置

    \[ \begin{align*} ^{b}{\textrm{T}_g}^{(1)} \hspace{0.2em} ^{g}\textrm{T}_c \hspace{0.2em} ^{c}{\textrm{T}_t}^{(1)} &= \hspace{0.1em} ^{b}{\textrm{T}_g}^{(2)} \hspace{0.2em} ^{g}\textrm{T}_c \hspace{0.2em} ^{c}{\textrm{T}_t}^{(2)} \\ (^{b}{\textrm{T}_g}^{(2)})^{-1} \hspace{0.2em} ^{b}{\textrm{T}_g}^{(1)} \hspace{0.2em} ^{g}\textrm{T}_c &= \hspace{0.1em} ^{g}\textrm{T}_c \hspace{0.2em} ^{c}{\textrm{T}_t}^{(2)} (^{c}{\textrm{T}_t}^{(1)})^{-1} \\ \textrm{A}_i \textrm{X} &= \textrm{X} \textrm{B}_i \\ \end{align*} \]

  • 用于眼对手配置

    \[ \begin{align*} ^{g}{\textrm{T}_b}^{(1)} \hspace{0.2em} ^{b}\textrm{T}_c \hspace{0.2em} ^{c}{\textrm{T}_t}^{(1)} &= \hspace{0.1em} ^{g}{\textrm{T}_b}^{(2)} \hspace{0.2em} ^{b}\textrm{T}_c \hspace{0.2em} ^{c}{\textrm{T}_t}^{(2)} \\ (^{g}{\textrm{T}_b}^{(2)})^{-1} \hspace{0.2em} ^{g}{\textrm{T}_b}^{(1)} \hspace{0.2em} ^{b}\textrm{T}_c &= \hspace{0.1em} ^{b}\textrm{T}_c \hspace{0.2em} ^{c}{\textrm{T}_t}^{(2)} (^{c}{\textrm{T}_t}^{(1)})^{-1} \\ \textrm{A}_i \textrm{X} &= \textrm{X} \textrm{B}_i \\ \end{align*} \]

注意
更多信息可以在这个 网站 上找到。
需要至少2个具有非平行旋转轴的运动才能确定手眼变换。因此至少需要3个不同的姿态,但强烈建议使用更多的姿态。

◆ calibrateRobotWorldHandEye()

void cv::calibrateRobotWorldHandEye ( InputArrayOfArrays R_world2cam,
InputArrayOfArrays t_world2cam,
InputArrayOfArrays R_base2gripper,
InputArrayOfArrays t_base2gripper,
OutputArray R_base2world,
OutputArray t_base2world,
OutputArray R_gripper2cam,
OutputArray t_gripper2cam,
RobotWorldHandEyeCalibrationMethod method = CALIB_ROBOT_WORLD_HAND_EYE_SHAH )
Python
cv.calibrateRobotWorldHandEye(R_world2cam, t_world2cam, R_base2gripper, t_base2gripper[, R_base2world[, t_base2world[, R_gripper2cam[, t_gripper2cam[, method]]]]]) -> R_base2world, t_base2world, R_gripper2cam, t_gripper2cam

#include <opencv2/calib3d.hpp>

计算机器人-世界/手眼标定:\(_{}^{w}\textrm{T}_b\) 和 \(_{}^{c}\textrm{T}_g\)。

参数
[in]R_world2cam从将世界坐标系中的点变换到相机坐标系中的齐次矩阵中提取的旋转部分( \(_{}^{c}\textrm{T}_w\))。这是一个向量(vector<Mat>),其中包含从世界坐标系到相机坐标系的所有变换的旋转(3x3旋转矩阵或3x1旋转向量)。
[in]t_world2cam从将世界坐标系中的点变换到相机坐标系中的齐次矩阵中提取的平移部分( \(_{}^{c}\textrm{T}_w\))。这是一个向量(vector<Mat>),其中包含从世界坐标系到相机坐标系的所有变换的3x1平移向量。
[in]R_base2gripper从将机器人基座坐标系中的点变换到夹持器坐标系中的齐次矩阵中提取的旋转部分( \(_{}^{g}\textrm{T}_b\))。这是一个向量(vector<Mat>),其中包含从机器人基座坐标系到夹持器坐标系的所有变换的旋转(3x3旋转矩阵或3x1旋转向量)。
[in]t_base2gripper从将机器人基座坐标系中的点变换到夹持器坐标系中的齐次矩阵中提取的旋转部分( \(_{}^{g}\textrm{T}_b\))。这是一个向量(vector<Mat>),其中包含从机器人基座坐标系到夹持器坐标系的所有变换的3x1平移向量。
[out]R_base2world从将机器人基座坐标系中的点变换到世界坐标系中的齐次矩阵中提取的估计 (3x3) 旋转部分( \(_{}^{w}\textrm{T}_b\))。
[out]t_base2world从将机器人基座坐标系中的点变换到世界坐标系中的齐次矩阵中提取的估计 (3x1) 平移部分( \(_{}^{w}\textrm{T}_b\))。
[out]R_gripper2cam从将夹持器坐标系中的点变换到相机坐标系中的齐次矩阵中提取的估计 (3x3) 旋转部分( \(_{}^{c}\textrm{T}_g\))。
[out]t_gripper2cam从将夹持器坐标系中的点变换到相机坐标系中的齐次矩阵中提取的估计 (3x1) 平移部分( \(_{}^{c}\textrm{T}_g\))。
[in]method其中一种已实现的机器人-世界/手眼标定方法,参见 cv::RobotWorldHandEyeCalibrationMethod

该函数使用各种方法执行机器人-世界/手眼标定。一种方法是先估计旋转,然后估计平移(可分离解)

  • M. Shah,使用克罗内克积解决机器人-世界/手眼标定问题 [250]

另一种方法是同时估计旋转和平移(同时解),并实现了以下方法

  • A. Li, L. Wang, 和 D. Wu,使用双四元数和克罗内克积同时进行机器人-世界和手眼标定 [168]

下图描述了机器人-世界/手眼标定问题,其中必须估计机器人和世界坐标系之间以及机器人夹持器(“手”)和安装在机器人末端执行器上的相机(“眼”)之间的变换。

标定过程如下:

  • 使用静态校准图案来估计目标框架与相机框架之间的变换
  • 移动机器人夹持器以获取多个姿态
  • 对于每个姿态,使用机器人运动学记录夹持器框架和机器人基座框架之间的齐次变换

    \[ \begin{bmatrix} X_g\\ Y_g\\ Z_g\\ 1 \end{bmatrix} = \begin{bmatrix} _{}^{g}\textrm{R}_b & _{}^{g}\textrm{t}_b \\ 0_{1 \times 3} & 1 \end{bmatrix} \begin{bmatrix} X_b\\ Y_b\\ Z_b\\ 1 \end{bmatrix} \]

  • 对于每个姿态,使用例如基于2D-3D点对应关系的姿态估计方法(PnP)记录校准目标框架(世界框架)与相机框架之间的齐次变换

    \[ \begin{bmatrix} X_c\\ Y_c\\ Z_c\\ 1 \end{bmatrix} = \begin{bmatrix} _{}^{c}\textrm{R}_w & _{}^{c}\textrm{t}_w \\ 0_{1 \times 3} & 1 \end{bmatrix} \begin{bmatrix} X_w\\ Y_w\\ Z_w\\ 1 \end{bmatrix} \]

机器人-世界/手眼标定程序返回以下齐次变换

\[ \begin{bmatrix} X_w\\ Y_w\\ Z_w\\ 1 \end{bmatrix} = \begin{bmatrix} _{}^{w}\textrm{R}_b & _{}^{w}\textrm{t}_b \\ 0_{1 \times 3} & 1 \end{bmatrix} \begin{bmatrix} X_b\\ Y_b\\ Z_b\\ 1 \end{bmatrix} \]

\[ \begin{bmatrix} X_c\\ Y_c\\ Z_c\\ 1 \end{bmatrix} = \begin{bmatrix} _{}^{c}\textrm{R}_g & _{}^{c}\textrm{t}_g \\ 0_{1 \times 3} & 1 \end{bmatrix} \begin{bmatrix} X_g\\ Y_g\\ Z_g\\ 1 \end{bmatrix} \]

此问题也称为求解 \(\mathbf{A}\mathbf{X}=\mathbf{Z}\mathbf{B}\) 方程,其中

  • \(\mathbf{A} \Leftrightarrow \hspace{0.1em} _{}^{c}\textrm{T}_w\)
  • \(\mathbf{X} \Leftrightarrow \hspace{0.1em} _{}^{w}\textrm{T}_b\)
  • \(\mathbf{Z} \Leftrightarrow \hspace{0.1em} _{}^{c}\textrm{T}_g\)
  • \(\mathbf{B} \Leftrightarrow \hspace{0.1em} _{}^{g}\textrm{T}_b\)
注意
至少需要3个测量值(输入向量大小必须大于或等于3)。

◆ calibrationMatrixValues()

void cv::calibrationMatrixValues ( InputArray cameraMatrix,
Size imageSize,
double apertureWidth,
double apertureHeight,
double & fovx,
double & fovy,
double & focalLength,
Point2d & principalPoint,
double & aspectRatio )
Python
cv.calibrationMatrixValues(cameraMatrix, imageSize, apertureWidth, apertureHeight) -> fovx, fovy, focalLength, principalPoint, aspectRatio

#include <opencv2/calib3d.hpp>

从相机内参矩阵计算有用的相机特性。

参数
cameraMatrix输入相机内参矩阵,可通过 calibrateCamerastereoCalibrate 估计。
imageSize输入图像尺寸(像素)。
apertureWidth传感器物理宽度,单位为毫米。
apertureHeight传感器物理高度,单位为毫米。
fovx输出视场角,单位为度,沿水平传感器轴线。
fovy输出视场角,单位为度,沿垂直传感器轴线。
focalLength镜头焦距,单位为毫米。
principalPoint主点,单位为毫米。
aspectRatio\(f_y/f_x\)

该函数根据先前估计的相机矩阵计算各种有用的相机特性。

注意
请记住,统一的度量单位“mm”代表为棋盘格间距选择的任何度量单位(因此可以是任何值)。

◆ checkChessboard()

bool cv::checkChessboard ( InputArray img,
Size size (大小) )
Python
cv.checkChessboard(img, size) -> retval

#include <opencv2/calib3d.hpp>

◆ composeRT()

void cv::composeRT ( InputArray rvec1,
InputArray tvec1,
InputArray rvec2,
InputArray tvec2,
OutputArray rvec3,
OutputArray tvec3,
OutputArray dr3dr1 = noArray(),
OutputArray dr3dt1 = noArray(),
OutputArray dr3dr2 = noArray(),
OutputArray dr3dt2 = noArray(),
OutputArray dt3dr1 = noArray(),
OutputArray dt3dt1 = noArray(),
OutputArray dt3dr2 = noArray(),
OutputArray dt3dt2 = noArray() )
Python
cv.composeRT(rvec1, tvec1, rvec2, tvec2[, rvec3[, tvec3[, dr3dr1[, dr3dt1[, dr3dr2[, dr3dt2[, dt3dr1[, dt3dt1[, dt3dr2[, dt3dt2]]]]]]]]]]) -> rvec3, tvec3, dr3dr1, dr3dt1, dr3dr2, dt3dt2, dt3dr1, dt3dt1, dt3dr2, dt3dt2

#include <opencv2/calib3d.hpp>

结合两个旋转和平移变换。

参数
rvec1第一个旋转向量。
tvec1第一个平移向量。
rvec2第二个旋转向量。
tvec2第二个平移向量。
rvec3叠加的输出旋转向量。
tvec3叠加的输出平移向量。
dr3dr1rvec3 对 rvec1 的可选输出导数
dr3dt1rvec3 对 tvec1 的可选输出导数
dr3dr2rvec3 对 rvec2 的可选输出导数
dr3dt2rvec3 对 tvec2 的可选输出导数
dt3dr1tvec3 对 rvec1 的可选输出导数
dt3dt1tvec3 对 tvec1 的可选输出导数
dt3dr2tvec3 对 rvec2 的可选输出导数
dt3dt2tvec3 对 tvec2 的可选输出导数

函数计算

\[\begin{array}{l} \texttt{rvec3} = \mathrm{rodrigues} ^{-1} \left ( \mathrm{rodrigues} ( \texttt{rvec2} ) \cdot \mathrm{rodrigues} ( \texttt{rvec1} ) \right ) \\ \texttt{tvec3} = \mathrm{rodrigues} ( \texttt{rvec2} ) \cdot \texttt{tvec1} + \texttt{tvec2} \end{array} ,\]

其中 \(\mathrm{rodrigues}\) 表示从旋转向量到旋转矩阵的变换,\(\mathrm{rodrigues}^{-1}\) 表示逆变换。有关详细信息,请参见 Rodrigues

此外,这些函数还可以计算输出向量对输入向量的导数(参见 matMulDeriv )。这些函数在 stereoCalibrate 内部使用,但也可用于您自己的代码中,其中 Levenberg-Marquardt 或其他基于梯度的求解器用于优化包含矩阵乘法的函数。

◆ computeCorrespondEpilines()

void cv::computeCorrespondEpilines ( InputArray points,
int whichImage,
InputArray F,
OutputArray lines )
Python
cv.computeCorrespondEpilines(points, whichImage, F[, lines]) -> lines

#include <opencv2/calib3d.hpp>

对于立体像对中一幅图像上的点,计算另一幅图像中相应的极线。

参数
points输入点。\(N \times 1\) 或 \(1 \times N\) 类型的 CV_32FC2 矩阵或 vector<Point2f>。
whichImage包含点的图像索引(1 或 2)。
F基本矩阵,可以使用 findFundamentalMatstereoRectify 估计。
lines对应于另一幅图像中点的对极线的输出向量。每条线 \(ax + by + c=0\) 由 3 个数字 \((a, b, c)\) 编码。

对于立体像对两幅图像中的每个点,该函数查找另一幅图像中对应对极线的方程。

根据基本矩阵定义(参见 findFundamentalMat ),当 whichImage=1 时,第一幅图像中点 \(p^{(1)}_i\) 在第二幅图像中的直线 \(l^{(2)}_i\) 计算为

\[l^{(2)}_i = F p^{(1)}_i\]

反之,当 whichImage=2 时,\(l^{(1)}_i\) 从 \(p^{(2)}_i\) 计算为

\[l^{(1)}_i = F^T p^{(2)}_i\]

线系数定义为按比例缩放。它们被归一化,使得 \(a_i^2+b_i^2=1\)。

◆ convertPointsFromHomogeneous()

void cv::convertPointsFromHomogeneous ( InputArray src,
OutputArray dst )
Python
cv.convertPointsFromHomogeneous(src[, dst]) -> dst

#include <opencv2/calib3d.hpp>

将点从齐次空间转换为欧几里得空间。

参数
srcN维点的输入向量。
dstN-1维点的输出向量。

该函数使用透视投影将齐次点转换为欧几里德空间。也就是说,每个点 (x1, x2, ... x(n-1), xn) 都转换为 (x1/xn, x2/xn, ..., x(n-1)/xn)。当 xn=0 时,输出点坐标将为 (0,0,0,...)。

◆ convertPointsHomogeneous()

void cv::convertPointsHomogeneous ( InputArray src,
OutputArray dst )

#include <opencv2/calib3d.hpp>

在齐次坐标之间转换点。

参数
src2D、3D 或 4D 点的输入数组或向量。
dst2D、3D 或 4D 点的输出向量。

该函数通过调用 convertPointsToHomogeneousconvertPointsFromHomogeneous 将 2D 或 3D 点从/转换为齐次坐标。

注意
该函数已过时。请改用前两个函数之一。

◆ convertPointsToHomogeneous()

void cv::convertPointsToHomogeneous ( InputArray src,
OutputArray dst )
Python
cv.convertPointsToHomogeneous(src[, dst]) -> dst

#include <opencv2/calib3d.hpp>

将点从欧几里得空间转换为齐次空间。

参数
srcN维点的输入向量。
dstN+1 维点的输出向量。

该函数通过在点坐标元组中添加 1 将点从欧几里德空间转换为齐次空间。也就是说,每个点 (x1, x2, ..., xn) 都转换为 (x1, x2, ..., xn, 1)。

◆ correctMatches()

void cv::correctMatches ( InputArray F,
InputArray points1,
InputArray points2,
OutputArray newPoints1,
OutputArray newPoints2 )
Python
cv.correctMatches(F, points1, points2[, newPoints1[, newPoints2]]) -> newPoints1, newPoints2

#include <opencv2/calib3d.hpp>

精细化对应点的坐标。

参数
F3x3 基本矩阵。
points1包含第一组点的 1xN 数组。
points2包含第二组点的 1xN 数组。
newPoints1优化后的 points1。
newPoints2优化后的 points2。

该函数实现了最佳三角测量方法(详见多视图几何 [120])。对于每个给定的点对应关系 points1[i] <-> points2[i] 和基本矩阵 F,它计算校正后的对应关系 newPoints1[i] <-> newPoints2[i],以最小化几何误差 \(d(points1[i], newPoints1[i])^2 + d(points2[i],newPoints2[i])^2\)(其中 \(d(a,b)\) 是点 \(a\) 和 \(b\) 之间的几何距离),并满足对极约束 \(newPoints2^T \cdot F \cdot newPoints1 = 0\)。

◆ decomposeEssentialMat()

void cv::decomposeEssentialMat ( InputArray E,
OutputArray R1,
OutputArray R2,
OutputArray t )
Python
cv.decomposeEssentialMat(E[, R1[, R2[, t]]]) -> R1, R2, t

#include <opencv2/calib3d.hpp>

将本质矩阵分解为可能的旋转和平移。

参数
E输入的本质矩阵。
R1一个可能的旋转矩阵。
R2另一个可能的旋转矩阵。
t一个可能的平移。

此函数使用奇异值分解 (svd decomposition) [120] 分解本质矩阵 E。通常,E 的分解存在四种可能的姿态:\([R_1, t]\)、\([R_1, -t]\)、\([R_2, t]\)、\([R_2, -t]\)。

如果 E 给出了图像点 \(p_1\)(在第一张图像中)和 \(p_2\)(在第二张图像中)之间的对极约束 \([p_2; 1]^T A^{-T} E A^{-1} [p_1; 1] = 0\) ,那么任何元组 \([R_1, t]\)、\([R_1, -t]\)、\([R_2, t]\)、\([R_2, -t]\) 都是从第一个相机的坐标系到第二个相机的坐标系的基变换。然而,通过分解 E,只能得到平移的方向。因此,平移 t 以单位长度返回。

◆ decomposeHomographyMat()

int cv::decomposeHomographyMat ( InputArray H,
InputArray K,
OutputArrayOfArrays rotations,
OutputArrayOfArrays translations,
OutputArrayOfArrays normals )
Python
cv.decomposeHomographyMat(H, K[, rotations[, translations[, normals]]]) -> retval, rotations, translations, normals

#include <opencv2/calib3d.hpp>

将单应性矩阵分解为旋转、平移和平面法线。

参数
H两个图像之间的输入单应性矩阵。
K输入的相机内部矩阵。
rotations旋转矩阵数组。
translations平移矩阵数组。
normals平面法线矩阵数组。

此函数提取平面对象在两个视图之间的相对相机运动,并返回最多四个旋转、平移和平面法线的数学解元组。单应性矩阵 H 的分解详见 [186]

如果由平面引起的单应性矩阵 H 给出约束

\[s_i \vecthree{x'_i}{y'_i}{1} \sim H \vecthree{x_i}{y_i}{1}\]

在源图像点 \(p_i\) 和目标图像点 \(p'_i\) 上,那么 rotations[k] 和 translations[k] 的元组是从源相机坐标系到目标相机坐标系的基变换。然而,通过分解 H,只能得到由场景的(通常未知)深度归一化的平移,即其方向但具有归一化长度。

如果存在点对应关系,则通过应用正深度约束,即所有点必须位于相机前方,至少两个解可能进一步无效。

◆ decomposeProjectionMatrix()

void cv::decomposeProjectionMatrix ( InputArray projMatrix,
OutputArray cameraMatrix,
OutputArray rotMatrix,
OutputArray transVect,
OutputArray rotMatrixX = noArray(),
OutputArray rotMatrixY = noArray(),
OutputArray rotMatrixZ = noArray(),
OutputArray eulerAngles = noArray() )
Python
cv.decomposeProjectionMatrix(projMatrix[, cameraMatrix[, rotMatrix[, transVect[, rotMatrixX[, rotMatrixY[, rotMatrixZ[, eulerAngles]]]]]]]) -> cameraMatrix, rotMatrix, transVect, rotMatrixX, rotMatrixY, rotMatrixZ, eulerAngles

#include <opencv2/calib3d.hpp>

将投影矩阵分解为旋转矩阵和相机内参矩阵。

参数
projMatrix3x4 输入投影矩阵 P。
cameraMatrix输出 3x3 相机内部矩阵 \(\cameramatrix{A}\)。
rotMatrix输出 3x3 外部旋转矩阵 R。
transVect输出 4x1 平移向量 T。
rotMatrixX可选的 3x3 绕 x 轴旋转矩阵。
rotMatrixY可选的 3x3 绕 y 轴旋转矩阵。
rotMatrixZ可选的 3x3 绕 z 轴旋转矩阵。
eulerAngles可选的三元素向量,包含三个以度为单位的欧拉旋转角。

该函数将投影矩阵分解为校准矩阵和旋转矩阵以及相机位置。

它可选地返回三个旋转矩阵,每个轴一个,以及三个可在 OpenGL 中使用的欧拉角。请注意,始终存在不止一种围绕三个主轴的旋转序列,可以使物体具有相同的方向,例如参见 [254] 。返回的三个旋转矩阵和相应的三个欧拉角只是可能的解决方案之一。

该函数基于 RQDecomp3x3

◆ drawChessboardCorners()

void cv::drawChessboardCorners ( InputOutputArray 图像,
Size patternSize,
InputArray corners,
bool patternWasFound )
Python
cv.drawChessboardCorners(image, patternSize, corners, patternWasFound) -> 图像

#include <opencv2/calib3d.hpp>

渲染检测到的棋盘格角点。

参数
图像目标图像。它必须是 8 位彩色图像。
patternSize每个棋盘格行和列的内部角点数量 (patternSize = cv::Size(points_per_row,points_per_column))。
corners检测到的角点数组,是 findChessboardCorners 的输出。
patternWasFound指示是否找到完整棋盘格的参数。此处应传递 findChessboardCorners 的返回值。

该函数绘制检测到的单个棋盘格角点,如果未找到棋盘格,则绘制为红色圆圈,如果找到棋盘格,则绘制为用线连接的彩色角点。

◆ drawFrameAxes()

void cv::drawFrameAxes ( InputOutputArray 图像,
InputArray cameraMatrix,
InputArray distCoeffs,
InputArray rvec,
InputArray tvec,
float length,
int thickness = 3 )
Python
cv.drawFrameAxes(image, cameraMatrix, distCoeffs, rvec, tvec, length[, thickness]) -> 图像

#include <opencv2/calib3d.hpp>

根据姿态估计绘制世界/物体坐标系的轴。

另请参阅
solvePnP
参数
图像输入/输出图像。它必须有 1 或 3 个通道。通道数量不变。
cameraMatrix相机内部参数的 3x3 浮点矩阵输入。\(\cameramatrix{A}\)
distCoeffs畸变系数 \(\distcoeffs\) 的输入向量。如果向量为空,则假定畸变系数为零。
rvec旋转向量(参见 Rodrigues),与 tvec 一起将点从模型坐标系带到相机坐标系。
tvec平移向量。
length绘制的轴的长度,单位与 tvec 相同(通常为米)。
thickness绘制轴的线宽。

此函数根据相机坐标系绘制世界/对象坐标系的轴。OX 以红色绘制,OY 以绿色绘制,OZ 以蓝色绘制。

◆ estimateAffine2D() [1/2]

cv::Mat cv::estimateAffine2D ( InputArray from,
InputArray to,
OutputArray inliers = noArray(),
int method = RANSAC,
double ransacReprojThreshold = 3,
size_t maxIters = 2000,
double confidence = 0.99,
size_t refineIters = 10 )
Python
cv.estimateAffine2D(from_, to[, inliers[, method[, ransacReprojThreshold[, maxIters[, confidence[, refineIters]]]]]]) -> retval, inliers
cv.estimateAffine2D(pts1, pts2, params[, inliers]) -> retval, inliers

#include <opencv2/calib3d.hpp>

计算两个 2D 点集之间的最佳仿射变换。

它计算

\[ \begin{bmatrix} x\\ y\\ \end{bmatrix} = \begin{bmatrix} a_{11} & a_{12}\\ a_{21} & a_{22}\\ \end{bmatrix} \begin{bmatrix} X\\ Y\\ \end{bmatrix} + \begin{bmatrix} b_1\\ b_2\\ \end{bmatrix} \]

参数
from包含 \((X,Y)\) 的第一个输入 2D 点集。
to包含 \((x,y)\) 的第二个输入 2D 点集。
inliers输出向量,指示哪些点是内点(1-内点,0-外点)。
method用于计算变换的鲁棒方法。以下方法是可能的
  • RANSAC - 基于 RANSAC 的鲁棒方法
  • LMEDS - 最小中位数鲁棒方法,RANSAC 为默认方法。
ransacReprojThresholdRANSAC 算法中的最大重投影误差,用于将点视为内点。仅适用于 RANSAC。
maxIters鲁棒方法的最大迭代次数。
confidence估计变换的置信水平,介于 0 和 1 之间。通常 0.95 到 0.99 之间就足够了。过接近 1 的值会显著减慢估计速度。低于 0.8-0.9 的值可能导致估计变换不正确。
refineIters细化算法(Levenberg-Marquardt)的最大迭代次数。传递 0 将禁用细化,因此输出矩阵将是鲁棒方法的输出。
返回
输出 2D 仿射变换矩阵 \(2 \times 3\),如果无法估计变换则为空矩阵。返回的矩阵形式如下:

\[ \begin{bmatrix} a_{11} & a_{12} & b_1\\ a_{21} & a_{22} & b_2\\ \end{bmatrix} \]

该函数使用选定的鲁棒算法估计两个 2D 点集之间的最佳 2D 仿射变换。

然后,使用 Levenberg-Marquardt 方法进一步细化计算出的变换(仅使用内点),以进一步减小重投影误差。

注意
RANSAC 方法几乎可以处理任何比例的异常值,但需要一个阈值来区分内点和异常值。LMeDS 方法不需要任何阈值,但它仅在内点超过 50% 时才能正确工作。
另请参阅
estimateAffinePartial2D, getAffineTransform

◆ estimateAffine2D() [2/2]

cv::Mat cv::estimateAffine2D ( InputArray pts1,
InputArray pts2,
OutputArray inliers,
const UsacParams & params )
Python
cv.estimateAffine2D(from_, to[, inliers[, method[, ransacReprojThreshold[, maxIters[, confidence[, refineIters]]]]]]) -> retval, inliers
cv.estimateAffine2D(pts1, pts2, params[, inliers]) -> retval, inliers

#include <opencv2/calib3d.hpp>

◆ estimateAffine3D() [1/2]

cv::Mat cv::estimateAffine3D ( InputArray src,
InputArray dst,
double * scale = nullptr,
bool force_rotation = true )
Python
cv.estimateAffine3D(src, dst[, out[, inliers[, ransacThreshold[, confidence]]]]) -> retval, out, inliers
cv.estimateAffine3D(src, dst[, force_rotation]) -> retval, scale

#include <opencv2/calib3d.hpp>

计算两个 3D 点集之间的最佳仿射变换。

它计算 \(R,s,t\) 最小化 \(\sum{i} dst_i - c \cdot R \cdot src_i \) ,其中 \(R\) 是一个 3x3 旋转矩阵,\(t\) 是一个 3x1 平移向量,\(s\) 是一个标量尺寸值。这是 Umeyama [284] 算法的实现。估计的仿射变换具有齐次比例,是具有 7 个自由度的仿射变换的一个子类。配对点集需要至少包含 3 个点。

参数
src第一个输入 3D 点集。
dst第二个输入 3D 点集。
scale如果传入 null,则比例参数 c 将被假定为 1.0。否则,指向的变量将被设置为最佳比例。
force_rotation如果为 true,则返回的旋转永远不会是反射。这可能是意料之外的,例如在优化右旋和左旋坐标系之间的变换时。
返回
3D 仿射变换矩阵 \(3 \times 4\),形式为

\[T = \begin{bmatrix} R & t\\ \end{bmatrix} \]

◆ estimateAffine3D() [2/2]

int cv::estimateAffine3D ( InputArray src,
InputArray dst,
OutputArray out,
OutputArray inliers,
double ransacThreshold = 3,
double confidence = 0.99 )
Python
cv.estimateAffine3D(src, dst[, out[, inliers[, ransacThreshold[, confidence]]]]) -> retval, out, inliers
cv.estimateAffine3D(src, dst[, force_rotation]) -> retval, scale

#include <opencv2/calib3d.hpp>

计算两个 3D 点集之间的最佳仿射变换。

它计算

\[ \begin{bmatrix} x\\ y\\ z\\ \end{bmatrix} = \begin{bmatrix} a_{11} & a_{12} & a_{13}\\ a_{21} & a_{22} & a_{23}\\ a_{31} & a_{32} & a_{33}\\ \end{bmatrix} \begin{bmatrix} X\\ Y\\ Z\\ \end{bmatrix} + \begin{bmatrix} b_1\\ b_2\\ b_3\\ \end{bmatrix} \]

参数
src第一个输入 3D 点集,包含 \((X,Y,Z)\)。
dst第二个输入 3D 点集,包含 \((x,y,z)\)。
out输出 3D 仿射变换矩阵 \(3 \times 4\),形式为

\[ \begin{bmatrix} a_{11} & a_{12} & a_{13} & b_1\\ a_{21} & a_{22} & a_{23} & b_2\\ a_{31} & a_{32} & a_{33} & b_3\\ \end{bmatrix} \]

inliers输出向量,指示哪些点是内点(1-内点,0-外点)。
ransacThresholdRANSAC 算法中最大的重投影误差,用于将点视为内点。
confidence估计变换的置信水平,介于 0 和 1 之间。通常 0.95 到 0.99 之间就足够了。过接近 1 的值会显著减慢估计速度。低于 0.8-0.9 的值可能导致估计变换不正确。

该函数使用 RANSAC 算法估计两个 3D 点集之间的最佳 3D 仿射变换。

◆ estimateAffinePartial2D()

cv::Mat cv::estimateAffinePartial2D ( InputArray from,
InputArray to,
OutputArray inliers = noArray(),
int method = RANSAC,
double ransacReprojThreshold = 3,
size_t maxIters = 2000,
double confidence = 0.99,
size_t refineIters = 10 )
Python
cv.estimateAffinePartial2D(from_, to[, inliers[, method[, ransacReprojThreshold[, maxIters[, confidence[, refineIters]]]]]]) -> retval, inliers

#include <opencv2/calib3d.hpp>

计算两个 2D 点集之间的具有 4 个自由度的最佳受限仿射变换。

参数
from第一个输入 2D 点集。
to第二个输入 2D 点集。
inliers输出向量,指示哪些点是内点。
method用于计算变换的鲁棒方法。以下方法是可能的
  • RANSAC - 基于 RANSAC 的鲁棒方法
  • LMEDS - 最小中位数鲁棒方法,RANSAC 为默认方法。
ransacReprojThresholdRANSAC 算法中的最大重投影误差,用于将点视为内点。仅适用于 RANSAC。
maxIters鲁棒方法的最大迭代次数。
confidence估计变换的置信水平,介于 0 和 1 之间。通常 0.95 到 0.99 之间就足够了。过接近 1 的值会显著减慢估计速度。低于 0.8-0.9 的值可能导致估计变换不正确。
refineIters细化算法(Levenberg-Marquardt)的最大迭代次数。传递 0 将禁用细化,因此输出矩阵将是鲁棒方法的输出。
返回
输出 2D 仿射变换(4 个自由度)矩阵 \(2 \times 3\),如果无法估计变换则为空矩阵。

该函数估计两个 2D 点集之间具有 4 个自由度(仅限于平移、旋转和均匀缩放的组合)的最佳 2D 仿射变换。使用选定的算法进行鲁棒估计。

然后,使用 Levenberg-Marquardt 方法进一步细化计算出的变换(仅使用内点),以进一步减小重投影误差。

估计的变换矩阵为

\[ \begin{bmatrix} \cos(\theta) \cdot s & -\sin(\theta) \cdot s & t_x \\ \sin(\theta) \cdot s & \cos(\theta) \cdot s & t_y \end{bmatrix} \]

其中 \(\theta\) 是旋转角度,\(s\) 是缩放因子,\(t_x, t_y\) 分别是 \(x, y\) 轴上的平移。

注意
RANSAC 方法几乎可以处理任何比例的异常值,但需要一个阈值来区分内点和异常值。LMeDS 方法不需要任何阈值,但它仅在内点超过 50% 时才能正确工作。
另请参阅
estimateAffine2D, getAffineTransform

◆ estimateChessboardSharpness()

Scalar cv::estimateChessboardSharpness ( InputArray 图像,
Size patternSize,
InputArray corners,
float rise_distance = 0.8F,
bool vertical = false,
OutputArray sharpness = noArray() )
Python
cv.estimateChessboardSharpness(image, patternSize, corners[, rise_distance[, vertical[, sharpness]]]) -> retval, sharpness

#include <opencv2/calib3d.hpp>

估计检测到的棋盘格的清晰度。

图像清晰度和亮度是准确相机校准的关键参数。为了获取这些参数以过滤掉有问题的校准图像,此方法通过从黑到白棋盘格中心移动来计算边缘轮廓。在此基础上,计算从黑到白过渡所需的像素数。该过渡区域的宽度很好地表明了棋盘格成像的清晰度,应低于约 3.0 像素。

参数
图像用于查找棋盘角点的灰度图像
patternSize找到的棋盘格图案大小
cornersfindChessboardCornersSB 找到的角点
rise_distance上升距离 0.8 表示最终信号强度的 10%...90%
vertical默认情况下计算水平线的边缘响应
sharpness可选输出数组,包含计算出的边缘响应的清晰度值(见描述)

可选的锐度数组类型为 CV_32FC1,每行包含以下五个条目,对应于每个计算出的轮廓:0 = 图像中底层边缘的 x 坐标 1 = 图像中底层边缘的 y 坐标 2 = 过渡区域的宽度(锐度) 3 = 黑色单元格中的信号强度(最小亮度) 4 = 白色单元格中的信号强度(最大亮度)

返回
Scalar(平均清晰度, 平均最小亮度, 平均最大亮度, 0)

◆ estimateTranslation2D()

cv::Vec2d cv::estimateTranslation2D ( InputArray from,
InputArray to,
OutputArray inliers = noArray(),
int method = RANSAC,
double ransacReprojThreshold = 3,
size_t maxIters = 2000,
double confidence = 0.99,
size_t refineIters = 0 )
Python
cv.estimateTranslation2D(from_, to[, inliers[, method[, ransacReprojThreshold[, maxIters[, confidence[, refineIters]]]]]]) -> retval, inliers

#include <opencv2/calib3d.hpp>

计算两个 2D 点集之间的纯 2D 平移。

它计算

\[ \begin{bmatrix} x\\ y \end{bmatrix} = \begin{bmatrix} 1 & 0\\ 0 & 1 \end{bmatrix} \begin{bmatrix} X\\ Y \end{bmatrix} + \begin{bmatrix} t_x\\ t_y \end{bmatrix}. \]

参数
from包含 \((X,Y)\) 的第一个输入 2D 点集。
to包含 \((x,y)\) 的第二个输入 2D 点集。
inliers输出向量,指示哪些点是内点(1-内点,0-外点)。
method用于计算变换的鲁棒方法。以下方法是可能的
  • RANSAC - 基于 RANSAC 的鲁棒方法
  • LMEDS - 最小中位数鲁棒方法,RANSAC 为默认方法。
ransacReprojThresholdRANSAC 算法中的最大重投影误差,用于将点视为内点。仅适用于 RANSAC。
maxIters鲁棒方法的最大迭代次数。
confidence估计变换的置信度,介于 0 和 1 之间。通常 0.95 到 0.99 之间就足够了。过接近 1 的值会显著减慢估计速度。低于 0.8-0.9 的值可能导致估计变换不正确。
refineIters细化算法的最大迭代次数。对于纯平移,内点上的最小二乘解是闭式解,因此建议传递 0(不进行额外细化)。
返回
一个 2D 平移向量 \([t_x, t_y]^T\),作为 cv::Vec2d。如果无法估计平移,则两个分量都设置为 NaN,并且如果提供了 inliers,则掩码将填充零。
转换为 2x3 变换矩阵

\[ \begin{bmatrix} 1 & 0 & t_x\\ 0 & 1 & t_y \end{bmatrix} \]

cv::Vec2d t = cv::estimateTranslation2D(from, to, inliers);
cv::Mat T = (cv::Mat_<double>(2,3) << 1,0,t[0], 0,1,t[1]);
派生自 Mat 的模板矩阵类。
定义于 mat.hpp:2296
n 维密集数组类
定义于 mat.hpp:840
cv::Vec2d estimateTranslation2D(InputArray from, InputArray to, OutputArray inliers=noArray(), int method=RANSAC, double ransacReprojThreshold=3, size_t maxIters=2000, double confidence=0.99, size_t refineIters=0)
计算两个 2D 点集之间的纯 2D 平移。

该函数使用选定的鲁棒算法估计两个 2D 点集之间的纯 2D 平移。内点由重投影误差阈值确定。

注意
RANSAC 方法几乎可以处理任何比例的异常值,但需要一个阈值来区分内点和异常值。LMeDS 方法不需要任何阈值,但它仅在内点超过 50% 时才能正确工作。
另请参阅
estimateAffine2D, estimateAffinePartial2D, getAffineTransform

◆ estimateTranslation3D()

int cv::estimateTranslation3D ( InputArray src,
InputArray dst,
OutputArray out,
OutputArray inliers,
double ransacThreshold = 3,
double confidence = 0.99 )
Python
cv.estimateTranslation3D(src, dst[, out[, inliers[, ransacThreshold[, confidence]]]]) -> retval, out, inliers

#include <opencv2/calib3d.hpp>

计算两个 3D 点集之间的最佳平移。

它计算

\[ \begin{bmatrix} x\\ y\\ z\\ \end{bmatrix} = \begin{bmatrix} X\\ Y\\ Z\\ \end{bmatrix} + \begin{bmatrix} b_1\\ b_2\\ b_3\\ \end{bmatrix} \]

参数
src第一个输入 3D 点集,包含 \((X,Y,Z)\)。
dst第二个输入 3D 点集,包含 \((x,y,z)\)。
out输出 3D 平移向量 \(3 \times 1\),形式为

\[ \begin{bmatrix} b_1 \\ b_2 \\ b_3 \\ \end{bmatrix} \]

inliers输出向量,指示哪些点是内点(1-内点,0-外点)。
ransacThresholdRANSAC 算法中最大的重投影误差,用于将点视为内点。
confidence估计变换的置信水平,介于 0 和 1 之间。通常 0.95 到 0.99 之间就足够了。过接近 1 的值会显著减慢估计速度。低于 0.8-0.9 的值可能导致估计变换不正确。

该函数使用 RANSAC 算法估计两个 3D 点集之间的最佳 3D 平移。

◆ filterHomographyDecompByVisibleRefpoints()

void cv::filterHomographyDecompByVisibleRefpoints ( InputArrayOfArrays rotations,
InputArrayOfArrays normals,
InputArray beforePoints,
InputArray afterPoints,
OutputArray possibleSolutions,
InputArray pointsMask = noArray() )
Python
cv.filterHomographyDecompByVisibleRefpoints(rotations, normals, beforePoints, afterPoints[, possibleSolutions[, pointsMask]]) -> possibleSolutions

#include <opencv2/calib3d.hpp>

基于附加信息过滤单应性分解结果。

参数
rotations旋转矩阵向量。
normals平面法线矩阵向量。
beforePoints在应用单应性变换之前(校正后)的可见参考点向量
afterPoints应用单应性变换之后(校正后)的可见参考点向量
possibleSolutions经过滤波后的可行解集(整数索引)向量
pointsMask可选的 Mat/Vector 8u 类型,表示 findHomography 函数给出的内点掩码

该函数旨在根据 [186] 中描述的附加信息过滤 decomposeHomographyMat 的输出。该方法的总结:decomposeHomographyMat 函数返回 2 个唯一解及其“反向”解,总共有 4 个解。如果我们能够访问应用单应性变换前后相机帧中可见的点集,我们可以通过验证哪些单应性变换与所有可见参考点都在相机前方一致来确定哪些是真正的潜在解,哪些是反向解。输入保持不变;过滤后的解集以现有解集的索引形式返回。

◆ filterSpeckles()

void cv::filterSpeckles ( InputOutputArray img,
double newVal,
int maxSpeckleSize,
double maxDiff,
InputOutputArray buf = noArray() )
Python
cv.filterSpeckles(img, newVal, maxSpeckleSize, maxDiff[, buf]) -> img, buf

#include <opencv2/calib3d.hpp>

过滤视差图中的细小噪声点(斑点)。

参数
img输入的 16 位有符号视差图像
newVal用于涂抹斑点的视差值
maxSpeckleSize将其视为斑点的最大斑点尺寸。更大的斑点不受算法影响
maxDiff相邻视差像素之间的最大差异,以将它们放入同一斑点。请注意,由于 StereoBMStereoSGBM 和其他算法可能返回定点视差图,其中视差值乘以 16,因此在指定此参数值时应考虑此比例因子。
buf可选的临时缓冲区,以避免函数内部的内存分配。

◆ find4QuadCornerSubpix()

bool cv::find4QuadCornerSubpix ( InputArray img,
InputOutputArray corners,
Size region_size )
Python
cv.find4QuadCornerSubpix(img, corners, region_size) -> retval, corners

#include <opencv2/calib3d.hpp>

寻找棋盘格角点的亚像素级精确位置

◆ findChessboardCorners()

bool cv::findChessboardCorners ( InputArray 图像,
Size patternSize,
OutputArray corners,
int flags = CALIB_CB_ADAPTIVE_THRESH+CALIB_CB_NORMALIZE_IMAGE )
Python
cv.findChessboardCorners(image, patternSize[, corners[, flags]]) -> retval, corners

#include <opencv2/calib3d.hpp>

寻找棋盘格内角点的位置。

参数
图像源棋盘视图。它必须是 8 位灰度或彩色图像。
patternSize每个棋盘格行和列的内部角点数量 ( patternSize = cv::Size(points_per_row,points_per_colum) = cv::Size(columns,rows) )。
corners检测到的角点的输出数组。
flags (标志)各种操作标志,可以是零或以下值的组合
  • CALIB_CB_ADAPTIVE_THRESH 使用自适应阈值将图像转换为黑白,而不是固定的阈值级别(从平均图像亮度计算)。
  • CALIB_CB_NORMALIZE_IMAGE 在应用固定或自适应阈值之前,使用 equalizeHist 归一化图像 gamma。
  • CALIB_CB_FILTER_QUADS 使用额外标准(如轮廓面积、周长、类似正方形的形状)在轮廓检索阶段过滤掉错误的四边形。
  • CALIB_CB_FAST_CHECK 对图像进行快速检查,查找棋盘格角点,如果没有找到则跳过调用。这可以显著加快在未检测到棋盘格的退化条件下的调用速度。
  • CALIB_CB_PLAIN 忽略所有其他标志。输入图像按原样处理。不进行图像处理以改进棋盘格的查找。这会加快函数的执行速度,但如果图像未事先以适当的方式二值化,则可能导致无法识别棋盘格。

该函数尝试确定输入图像是否为棋盘格图案的视图,并定位棋盘格内部角点。如果找到所有角点并按特定顺序放置(逐行,每行从左到右),则函数返回非零值。否则,如果函数未能找到所有角点或未能重新排序,则返回 0。例如,一个规则的棋盘格有 8 x 8 个方格和 7 x 7 个内部角点,即黑方格相互接触的点。检测到的坐标是近似值,为了更准确地确定它们的位置,函数调用 cornerSubPix。如果返回的坐标不够准确,您也可以使用不同参数的 cornerSubPix 函数。

检测和绘制棋盘角点的示例用法:

Size patternsize(8,6); //内部角点数
Mat gray = ....; //源图像
vector<Point2f> corners; //这将填充检测到的角点
//CALIB_CB_FAST_CHECK 在不包含任何棋盘格角点的图像上节省大量时间
//如果图像不包含任何棋盘格角点,CALIB_CB_FAST_CHECK 可节省大量时间
bool patternfound = findChessboardCorners(gray, patternsize, corners,
if(patternfound)
cornerSubPix(gray, corners, Size(11, 11), Size(-1, -1),
TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 30, 0.1));
drawChessboardCorners(img, patternsize, Mat(corners), patternfound);
用于指定图像或矩形大小的模板类。
定义 types.hpp:335
定义迭代算法终止标准的类。
定义 types.hpp:893
void drawChessboardCorners(InputOutputArray image, Size patternSize, InputArray corners, bool patternWasFound)
渲染检测到的棋盘格角点。
bool findChessboardCorners(InputArray image, Size patternSize, OutputArray corners, int flags=CALIB_CB_ADAPTIVE_THRESH+CALIB_CB_NORMALIZE_IMAGE)
寻找棋盘格内角点的位置。
@ CALIB_CB_FAST_CHECK
定义 calib3d.hpp:592
@ CALIB_CB_ADAPTIVE_THRESH
定义 calib3d.hpp:589
@ CALIB_CB_NORMALIZE_IMAGE
定义 calib3d.hpp:590
Size2i Size
定义 types.hpp:370
void cornerSubPix(InputArray image, InputOutputArray corners, Size winSize, Size zeroZone, TermCriteria criteria)
优化角点位置(亚像素精度)。
注意
该函数要求棋盘格周围有空白空间(例如方形厚边框,越宽越好),以提高在各种环境下的检测鲁棒性。否则,如果没有边框且背景较暗,则外部黑方块无法正确分割,从而导致方块分组和排序算法失败。

使用 generate_pattern.py Python 脚本(创建校准图案)创建所需的棋盘格图案。

◆ findChessboardCornersSB() [1/2]

bool cv::findChessboardCornersSB ( InputArray 图像,
Size patternSize,
OutputArray corners,
int flags (标志),
OutputArray meta )
Python
cv.findChessboardCornersSB(image, patternSize[, corners[, flags]]) -> retval, corners
cv.findChessboardCornersSBWithMeta(image, patternSize, flags[, corners[, meta]]) -> retval, corners, meta

#include <opencv2/calib3d.hpp>

使用基于扇区的方法寻找棋盘格内角点的位置。

参数
图像源棋盘视图。它必须是 8 位灰度或彩色图像。
patternSize每个棋盘格行和列的内部角点数量 ( patternSize = cv::Size(points_per_row,points_per_colum) = cv::Size(columns,rows) )。
corners检测到的角点的输出数组。
flags (标志)各种操作标志,可以是零或以下值的组合
meta可选的检测到的角点输出数组(CV_8UC1 类型,大小 = cv::Size(columns,rows))。每个条目代表图案的一个角点,可以具有以下值之一:
  • 0 = 未附加元数据
  • 1 = 黑色单元格的左上角
  • 2 = 白色单元格的左上角
  • 3 = 带白色标记点的黑色单元格的左上角
  • 4 = 带黑色标记点的白色单元格的左上角(带标记情况下的图案原点,否则为第一个角点)

该函数类似于 findChessboardCorners,但使用通过盒式滤波器近似的局部 Radon 变换,对各种噪声更鲁棒,在大型图像上更快,并且能够直接返回内部棋盘格角点的亚像素位置。该方法基于论文 [78] "Accurate Detection and Localization of Checkerboard Corners for Calibration",该论文证明返回的亚像素位置比 cornerSubPix 返回的更准确,从而可以对要求高的应用进行精确的相机校准。

如果给定标志 CALIB_CB_LARGERCALIB_CB_MARKER,结果可以从可选的元数据数组中恢复。这两个标志都有助于使用超出相机视场的校准图案。这些超大图案允许更准确的校准,因为可以使用尽可能靠近图像边界的角点。为了在所有图像中保持一致的坐标系,可以使用可选标记(见下图)将棋盘格的原点移动到黑圆圈所在的位置。

注意
该函数要求棋盘格周围有白色边框,宽度大致与棋盘格的一个字段相同,以改善在各种环境中的检测。此外,由于局部 Radon 变换,对棋盘格外部的字段角点使用圆角是有益的。下图说明了为检测优化的示例棋盘格。但是,也可以使用任何其他棋盘格。

使用 generate_pattern.py Python 脚本(创建校准图案)创建相应的棋盘格图案

◆ findChessboardCornersSB() [2/2]

bool cv::findChessboardCornersSB ( InputArray 图像,
Size patternSize,
OutputArray corners,
int flags = 0 )
内联
Python
cv.findChessboardCornersSB(image, patternSize[, corners[, flags]]) -> retval, corners
cv.findChessboardCornersSBWithMeta(image, patternSize, flags[, corners[, meta]]) -> retval, corners, meta

#include <opencv2/calib3d.hpp>

这是一个重载的成员函数,为方便起见而提供。它与上述函数的区别仅在于所接受的参数不同。

此函数的调用图

◆ findCirclesGrid() [1/2]

bool cv::findCirclesGrid ( InputArray 图像,
Size patternSize,
OutputArray centers,
int flags (标志),
const Ptr< FeatureDetector > & blobDetector,
const CirclesGridFinderParameters & parameters )
Python
cv.findCirclesGrid(image, patternSize, flags, blobDetector, parameters[, centers]) -> retval, centers
cv.findCirclesGrid(image, patternSize[, centers[, flags[, blobDetector]]]) -> retval, centers

#include <opencv2/calib3d.hpp>

寻找圆网格中的中心点。

参数
图像输入圆的网格视图;它必须是 8 位灰度或彩色图像。
patternSize每行和每列的圆圈数量( patternSize = Size(points_per_row, points_per_colum) )。
centers检测到的中心的输出数组。
flags (标志)各种操作标志,可以是以下值之一
blobDetector特征检测器,用于查找诸如浅色背景上的深色圆圈之类的斑点。如果 blobDetector 为 NULL,则 image 表示候选点的 Point2f 数组。
parameters用于在网格图案中查找圆的结构。

该函数尝试确定输入图像是否包含圆形网格。如果是,则该函数定位圆心。如果所有圆心都已找到并按特定顺序放置(逐行,每行从左到右),则函数返回非零值。否则,如果函数未能找到所有角点或未能重新排序它们,则返回 0。

检测和绘制圆心的示例用法:

Size patternsize(7,7); //中心点数量
Mat gray = ...; //源图像
vector<Point2f> centers; //这将由检测到的中心填充
bool patternfound = findCirclesGrid(gray, patternsize, centers);
drawChessboardCorners(img, patternsize, Mat(centers), patternfound);
bool findCirclesGrid(InputArray image, Size patternSize, OutputArray centers, int flags, const Ptr< FeatureDetector > &blobDetector, const CirclesGridFinderParameters &parameters)
寻找圆网格中的中心点。
注意
该函数要求棋盘格周围有空白区域(例如方形厚边框,越宽越好),以提高在各种环境下的检测鲁棒性。

◆ findCirclesGrid() [2/2]

bool cv::findCirclesGrid ( InputArray 图像,
Size patternSize,
OutputArray centers,
int flags = CALIB_CB_SYMMETRIC_GRID,
const Ptr< FeatureDetector > & blobDetector = SimpleBlobDetector::create() )
Python
cv.findCirclesGrid(image, patternSize, flags, blobDetector, parameters[, centers]) -> retval, centers
cv.findCirclesGrid(image, patternSize[, centers[, flags[, blobDetector]]]) -> retval, centers

#include <opencv2/calib3d.hpp>

这是一个重载的成员函数,为方便起见而提供。它与上述函数的区别仅在于所接受的参数不同。

◆ findEssentialMat() [1/6]

Mat cv::findEssentialMat ( InputArray points1,
InputArray points2,
double focal,
Point2d pp,
int method,
double prob,
double 阈值 (threshold),
OutputArray mask )
Python
cv.findEssentialMat(points1, points2, cameraMatrix[, method[, prob[, threshold[, maxIters[, mask]]]]]) -> retval, mask
cv.findEssentialMat(points1, points2[, focal[, pp[, method[, prob[, threshold[, maxIters[, mask]]]]]]]) -> retval, mask
cv.findEssentialMat(points1, points2, cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2[, method[, prob[, threshold[, mask]]]]) -> retval, mask
cv.findEssentialMat(points1, points2, cameraMatrix1, cameraMatrix2, dist_coeff1, dist_coeff2, params[, mask]) -> retval, mask

#include <opencv2/calib3d.hpp>

这是一个重载的成员函数,为方便起见而提供。它与上述函数的区别仅在于所接受的参数不同。

◆ findEssentialMat() [2/6]

Mat cv::findEssentialMat ( InputArray points1,
InputArray points2,
double focal = 1.0,
Point2d pp = Point2d(0, 0),
int method = RANSAC,
double prob = 0.999,
double threshold = 1.0,
int maxIters = 1000,
OutputArray mask = noArray() )
Python
cv.findEssentialMat(points1, points2, cameraMatrix[, method[, prob[, threshold[, maxIters[, mask]]]]]) -> retval, mask
cv.findEssentialMat(points1, points2[, focal[, pp[, method[, prob[, threshold[, maxIters[, mask]]]]]]]) -> retval, mask
cv.findEssentialMat(points1, points2, cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2[, method[, prob[, threshold[, mask]]]]) -> retval, mask
cv.findEssentialMat(points1, points2, cameraMatrix1, cameraMatrix2, dist_coeff1, dist_coeff2, params[, mask]) -> retval, mask

#include <opencv2/calib3d.hpp>

这是一个重载的成员函数,为方便起见而提供。它与上述函数的区别仅在于所接受的参数不同。

参数
points1来自第一幅图像的 N 个(N >= 5)2D 点数组。点坐标应为浮点数(单精度或双精度)。
points2第二幅图像中的点数组,与 points1 大小和格式相同。
focal相机焦距。请注意,此函数假设 points1 和 points2 是来自具有相同焦距和主点的相机的特征点。
pp相机主点。
method计算基本矩阵的方法。
  • RANSAC 用于 RANSAC 算法。
  • LMEDS 用于 LMedS 算法。
阈值 (threshold)RANSAC 参数。它是从点到对极线在像素中的最大距离,超出此距离的点被视为离群点,不用于计算最终的基本矩阵。可以设置为 1-3 左右,具体取决于点定位的精度、图像分辨率和图像噪声。
prob仅用于 RANSAC 或 LMedS 方法的参数。它指定了估计矩阵正确的期望置信度(概率)。
maskN 个元素的输出数组,每个元素对离群点设置为 0,对其他点设置为 1。该数组仅在 RANSAC 和 LMedS 方法中计算。
maxIters鲁棒方法的最大迭代次数。

此函数与上面一个不同,它从焦距和主点计算相机内部矩阵。

\[A = \begin{bmatrix} f & 0 & x_{pp} \\ 0 & f & y_{pp} \\ 0 & 0 & 1 \end{bmatrix}\]

◆ findEssentialMat() [3/6]

Mat cv::findEssentialMat ( InputArray points1,
InputArray points2,
InputArray cameraMatrix,
int method,
double prob,
double 阈值 (threshold),
OutputArray mask )
Python
cv.findEssentialMat(points1, points2, cameraMatrix[, method[, prob[, threshold[, maxIters[, mask]]]]]) -> retval, mask
cv.findEssentialMat(points1, points2[, focal[, pp[, method[, prob[, threshold[, maxIters[, mask]]]]]]]) -> retval, mask
cv.findEssentialMat(points1, points2, cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2[, method[, prob[, threshold[, mask]]]]) -> retval, mask
cv.findEssentialMat(points1, points2, cameraMatrix1, cameraMatrix2, dist_coeff1, dist_coeff2, params[, mask]) -> retval, mask

#include <opencv2/calib3d.hpp>

这是一个重载的成员函数,为方便起见而提供。它与上述函数的区别仅在于所接受的参数不同。

◆ findEssentialMat() [4/6]

Mat cv::findEssentialMat ( InputArray points1,
InputArray points2,
InputArray cameraMatrix,
int method = RANSAC,
double prob = 0.999,
double threshold = 1.0,
int maxIters = 1000,
OutputArray mask = noArray() )
Python
cv.findEssentialMat(points1, points2, cameraMatrix[, method[, prob[, threshold[, maxIters[, mask]]]]]) -> retval, mask
cv.findEssentialMat(points1, points2[, focal[, pp[, method[, prob[, threshold[, maxIters[, mask]]]]]]]) -> retval, mask
cv.findEssentialMat(points1, points2, cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2[, method[, prob[, threshold[, mask]]]]) -> retval, mask
cv.findEssentialMat(points1, points2, cameraMatrix1, cameraMatrix2, dist_coeff1, dist_coeff2, params[, mask]) -> retval, mask

#include <opencv2/calib3d.hpp>

根据两幅图像中的对应点计算本质矩阵。

参数
points1来自第一幅图像的 N 个(N >= 5)2D 点数组。点坐标应为浮点数(单精度或双精度)。
points2第二幅图像中的点数组,与 points1 大小和格式相同。
cameraMatrix相机内部矩阵 \(\cameramatrix{A}\)。请注意,此函数假设 points1 和 points2 是来自具有相同相机内部矩阵的相机的特征点。如果此假设不适用于您的用例,请使用其他函数重载或 undistortPoints 并为两个相机使用 P = cv::NoArray() 将图像点转换为归一化图像坐标,这对于单位相机内部矩阵是有效的。当传递这些坐标时,将此参数传递为单位矩阵。
method计算本质矩阵的方法。
  • RANSAC 用于 RANSAC 算法。
  • LMEDS 用于 LMedS 算法。
prob仅用于 RANSAC 或 LMedS 方法的参数。它指定了估计矩阵正确的期望置信度(概率)。
阈值 (threshold)RANSAC 参数。它是从点到对极线在像素中的最大距离,超出此距离的点被视为离群点,不用于计算最终的基本矩阵。可以设置为 1-3 左右,具体取决于点定位的精度、图像分辨率和图像噪声。
maskN 个元素的输出数组,每个元素对离群点设置为 0,对其他点设置为 1。该数组仅在 RANSAC 和 LMedS 方法中计算。
maxIters鲁棒方法的最大迭代次数。

此函数基于 [214] 中的五点算法求解器估算本质矩阵。 [258] 也与此相关。对极几何由以下方程描述

\[[p_2; 1]^T K^{-T} E K^{-1} [p_1; 1] = 0\]

其中 \(E\) 是本质矩阵,\(p_1\) 和 \(p_2\) 分别是第一幅图像和第二幅图像中的对应点。此函数的结果可以进一步传递给 decomposeEssentialMatrecoverPose 以恢复相机之间的相对姿态。

◆ findEssentialMat() [5/6]

Mat cv::findEssentialMat ( InputArray points1,
InputArray points2,
InputArray cameraMatrix1,
InputArray cameraMatrix2,
InputArray dist_coeff1,
InputArray dist_coeff2,
OutputArray mask,
const UsacParams & params )
Python
cv.findEssentialMat(points1, points2, cameraMatrix[, method[, prob[, threshold[, maxIters[, mask]]]]]) -> retval, mask
cv.findEssentialMat(points1, points2[, focal[, pp[, method[, prob[, threshold[, maxIters[, mask]]]]]]]) -> retval, mask
cv.findEssentialMat(points1, points2, cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2[, method[, prob[, threshold[, mask]]]]) -> retval, mask
cv.findEssentialMat(points1, points2, cameraMatrix1, cameraMatrix2, dist_coeff1, dist_coeff2, params[, mask]) -> retval, mask

#include <opencv2/calib3d.hpp>

◆ findEssentialMat() [6/6]

Mat cv::findEssentialMat ( InputArray points1,
InputArray points2,
InputArray cameraMatrix1,
InputArray distCoeffs1,
InputArray cameraMatrix2,
InputArray distCoeffs2,
int method = RANSAC,
double prob = 0.999,
double threshold = 1.0,
OutputArray mask = noArray() )
Python
cv.findEssentialMat(points1, points2, cameraMatrix[, method[, prob[, threshold[, maxIters[, mask]]]]]) -> retval, mask
cv.findEssentialMat(points1, points2[, focal[, pp[, method[, prob[, threshold[, maxIters[, mask]]]]]]]) -> retval, mask
cv.findEssentialMat(points1, points2, cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2[, method[, prob[, threshold[, mask]]]]) -> retval, mask
cv.findEssentialMat(points1, points2, cameraMatrix1, cameraMatrix2, dist_coeff1, dist_coeff2, params[, mask]) -> retval, mask

#include <opencv2/calib3d.hpp>

根据两幅图像(可能来自两台不同的相机)中的对应点计算本质矩阵。

参数
points1来自第一幅图像的 N 个(N >= 5)2D 点数组。点坐标应为浮点数(单精度或双精度)。
points2第二幅图像中的点数组,与 points1 大小和格式相同。
cameraMatrix1第一个相机的相机矩阵 \(K = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\)。
cameraMatrix2第二个相机的相机矩阵 \(K = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\)。
distCoeffs1第一个相机的畸变系数输入向量 \((k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6[, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]])\) 包含 4、5、8、12 或 14 个元素。如果向量为 NULL/空,则假定畸变系数为零。
distCoeffs2第二个相机的畸变系数输入向量 \((k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6[, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]])\) 包含 4、5、8、12 或 14 个元素。如果向量为 NULL/空,则假定畸变系数为零。
method计算本质矩阵的方法。
  • RANSAC 用于 RANSAC 算法。
  • LMEDS 用于 LMedS 算法。
prob仅用于 RANSAC 或 LMedS 方法的参数。它指定了估计矩阵正确的期望置信度(概率)。
阈值 (threshold)RANSAC 参数。它是从点到对极线在像素中的最大距离,超出此距离的点被视为离群点,不用于计算最终的基本矩阵。可以设置为 1-3 左右,具体取决于点定位的精度、图像分辨率和图像噪声。
maskN 个元素的输出数组,每个元素对离群点设置为 0,对其他点设置为 1。该数组仅在 RANSAC 和 LMedS 方法中计算。

此函数基于 [214] 中的五点算法求解器估算本质矩阵。 [258] 也与此相关。对极几何由以下方程描述

\[[p_2; 1]^T K^{-T} E K^{-1} [p_1; 1] = 0\]

其中 \(E\) 是本质矩阵,\(p_1\) 和 \(p_2\) 分别是第一幅图像和第二幅图像中的对应点。此函数的结果可以进一步传递给 decomposeEssentialMatrecoverPose 以恢复相机之间的相对姿态。

◆ findFundamentalMat() [1/4]

Mat cv::findFundamentalMat ( InputArray points1,
InputArray points2,
int method,
double ransacReprojThreshold,
double confidence,
int maxIters,
OutputArray mask = noArray() )
Python
cv.findFundamentalMat(points1, points2, method, ransacReprojThreshold, confidence, maxIters[, mask]) -> retval, mask
cv.findFundamentalMat(points1, points2[, method[, ransacReprojThreshold[, confidence[, mask]]]]) -> retval, mask
cv.findFundamentalMat(points1, points2, params[, mask]) -> retval, mask

#include <opencv2/calib3d.hpp>

根据两幅图像中的对应点计算基础矩阵。

参数
points1来自第一幅图像的 N 个点数组。点坐标应为浮点数(单精度或双精度)。
points2第二幅图像中的点数组,与 points1 大小和格式相同。
method计算基本矩阵的方法。
ransacReprojThreshold仅用于 RANSAC 的参数。它是从点到对极线在像素中的最大距离,超出此距离的点被视为离群点,不用于计算最终的基本矩阵。可以设置为 1-3 左右,具体取决于点定位的精度、图像分辨率和图像噪声。
confidence仅用于 RANSAC 和 LMedS 方法的参数。它指定了估计矩阵正确的期望置信度(概率)。
[out]mask可选输出掩码
maxIters鲁棒方法的最大迭代次数。

对极几何由以下方程描述

\[[p_2; 1]^T F [p_1; 1] = 0\]

其中 \(F\) 是基本矩阵,\(p_1\) 和 \(p_2\) 分别是第一幅图像和第二幅图像中的对应点。

该函数使用上面列出的四种方法之一计算基本矩阵并返回找到的基本矩阵。通常只找到一个矩阵。但在 7 点算法的情况下,该函数可能返回最多 3 个解(\(9 \times 3\) 矩阵,按顺序存储所有 3 个矩阵)。

计算出的基本矩阵可以进一步传递给 computeCorrespondEpilines,该函数查找与指定点对应的对极线。它也可以传递给 stereoRectifyUncalibrated 来计算校正变换。

// 示例。使用 RANSAC 算法估计基本矩阵
int point_count = 100;
vector<Point2f> points1(point_count);
vector<Point2f> points2(point_count);
// 在此处初始化点...
for( int i = 0; i < point_count; i++ )
{
points1[i] = ...;
points2[i] = ...;
}
Mat fundamental_matrix =
findFundamentalMat(points1, points2, FM_RANSAC, 3, 0.99);
Mat findFundamentalMat(InputArray points1, InputArray points2, int method, double ransacReprojThreshold, double confidence, int maxIters, OutputArray mask=noArray())
根据两幅图像中的对应点计算基础矩阵。
@ FM_RANSAC
RANSAC算法。至少需要15个点。使用7点算法。
定义 calib3d.hpp:637

◆ findFundamentalMat() [2/4]

Mat cv::findFundamentalMat ( InputArray points1,
InputArray points2,
int method = FM_RANSAC,
double ransacReprojThreshold = 3.,
double confidence = 0.99,
OutputArray mask = noArray() )
Python
cv.findFundamentalMat(points1, points2, method, ransacReprojThreshold, confidence, maxIters[, mask]) -> retval, mask
cv.findFundamentalMat(points1, points2[, method[, ransacReprojThreshold[, confidence[, mask]]]]) -> retval, mask
cv.findFundamentalMat(points1, points2, params[, mask]) -> retval, mask

#include <opencv2/calib3d.hpp>

这是一个重载的成员函数,为方便起见而提供。它与上述函数的区别仅在于所接受的参数不同。

◆ findFundamentalMat() [3/4]

Mat cv::findFundamentalMat ( InputArray points1,
InputArray points2,
OutputArray mask,
const UsacParams & params )
Python
cv.findFundamentalMat(points1, points2, method, ransacReprojThreshold, confidence, maxIters[, mask]) -> retval, mask
cv.findFundamentalMat(points1, points2[, method[, ransacReprojThreshold[, confidence[, mask]]]]) -> retval, mask
cv.findFundamentalMat(points1, points2, params[, mask]) -> retval, mask

#include <opencv2/calib3d.hpp>

◆ findFundamentalMat() [4/4]

Mat cv::findFundamentalMat ( InputArray points1,
InputArray points2,
OutputArray mask,
int method = FM_RANSAC,
double ransacReprojThreshold = 3.,
double confidence = 0.99 )
Python
cv.findFundamentalMat(points1, points2, method, ransacReprojThreshold, confidence, maxIters[, mask]) -> retval, mask
cv.findFundamentalMat(points1, points2[, method[, ransacReprojThreshold[, confidence[, mask]]]]) -> retval, mask
cv.findFundamentalMat(points1, points2, params[, mask]) -> retval, mask

#include <opencv2/calib3d.hpp>

这是一个重载的成员函数,为方便起见而提供。它与上述函数的区别仅在于所接受的参数不同。

◆ findHomography() [1/3]

Mat cv::findHomography ( InputArray srcPoints,
InputArray dstPoints,
int method = 0,
double ransacReprojThreshold = 3,
OutputArray mask = noArray(),
const int maxIters = 2000,
const double confidence = 0.995 )
Python
cv.findHomography(srcPoints, dstPoints[, method[, ransacReprojThreshold[, mask[, maxIters[, confidence]]]]]) -> retval, mask
cv.findHomography(srcPoints, dstPoints, params[, mask]) -> retval, mask

#include <opencv2/calib3d.hpp>

寻找两个平面之间的透视变换。

参数
srcPoints原始平面中点的坐标,类型为 CV_32FC2 的矩阵或 vector<Point2f>。
dstPoints目标平面中点的坐标,类型为 CV_32FC2 的矩阵或 vector<Point2f>。
method用于计算单应性矩阵的方法。可能的方法如下:
  • 0 - 使用所有点的常规方法,即最小二乘法
  • RANSAC - 基于 RANSAC 的鲁棒方法
  • LMEDS - 最小中位数鲁棒方法
  • RHO - 基于 PROSAC 的鲁棒方法
ransacReprojThreshold将点对视为内点的最大允许重投影误差(仅用于 RANSAC 和 RHO 方法)。也就是说,如果

\[\| \texttt{dstPoints} _i - \texttt{convertPointsHomogeneous} ( \texttt{H} \cdot \texttt{srcPoints} _i) \|_2 > \texttt{ransacReprojThreshold}\]

那么点 \(i\) 被认为是离群点。如果 srcPoints 和 dstPoints 以像素为单位测量,通常将此参数设置为 1 到 10 之间是有意义的。
mask由鲁棒方法(RANSAC 或 LMeDS)设置的可选输出掩码。请注意,输入掩码值将被忽略。
maxItersRANSAC 的最大迭代次数。
confidence置信水平,介于 0 和 1 之间。

该函数找到并返回源平面和目标平面之间的透视变换 \(H\)

\[s_i \vecthree{x'_i}{y'_i}{1} \sim H \vecthree{x_i}{y_i}{1}\]

使得反向投影误差

\[\sum _i \left ( x'_i- \frac{h_{11} x_i + h_{12} y_i + h_{13}}{h_{31} x_i + h_{32} y_i + h_{33}} \right )^2+ \left ( y'_i- \frac{h_{21} x_i + h_{22} y_i + h_{23}}{h_{31} x_i + h_{32} y_i + h_{33}} \right )^2\]

最小化。如果参数 method 设置为默认值 0,函数将使用所有点对通过简单的最小二乘方案计算初始单应性估计。

然而,如果并非所有点对( \(srcPoints_i\),\(dstPoints_i\) )都符合刚性透视变换(即存在一些异常值),则此初始估计将很差。在这种情况下,您可以使用三种鲁棒方法之一。RANSAC、LMeDS 和 RHO 方法尝试许多不同的对应点对随机子集(每组四对,共线对被丢弃),使用此子集和简单的最小二乘算法估计单应性矩阵,然后计算计算出的单应性的质量/优劣(RANSAC 的内点数或 LMeDS 的最小中值重投影误差)。然后使用最佳子集生成单应性矩阵的初始估计和内点/异常值掩码。

无论是否使用鲁棒方法,计算出的单应性矩阵都会通过 Levenberg-Marquardt 方法进一步细化(鲁棒方法只使用内点),以进一步减小重投影误差。

RANSAC 和 RHO 方法几乎可以处理任何比例的异常值,但需要一个阈值来区分内点和异常值。LMeDS 方法不需要任何阈值,但它仅在内点超过 50% 时才能正确工作。最后,如果没有异常值且噪声较小,请使用默认方法(method=0)。

该函数用于查找初始内部和外部矩阵。单应性矩阵是按比例确定的。如果 \(h_{33}\) 非零,则将矩阵归一化,使得 \(h_{33}=1\)。

注意
如果无法估计 H 矩阵,将返回空矩阵。
另请参阅
getAffineTransform, estimateAffine2D, estimateAffinePartial2D, getPerspectiveTransform, warpPerspective, perspectiveTransform

◆ findHomography() [2/3]

Mat cv::findHomography ( InputArray srcPoints,
InputArray dstPoints,
OutputArray mask,
const UsacParams & params )
Python
cv.findHomography(srcPoints, dstPoints[, method[, ransacReprojThreshold[, mask[, maxIters[, confidence]]]]]) -> retval, mask
cv.findHomography(srcPoints, dstPoints, params[, mask]) -> retval, mask

#include <opencv2/calib3d.hpp>

◆ findHomography() [3/3]

Mat cv::findHomography ( InputArray srcPoints,
InputArray dstPoints,
OutputArray mask,
int method = 0,
double ransacReprojThreshold = 3 )
Python
cv.findHomography(srcPoints, dstPoints[, method[, ransacReprojThreshold[, mask[, maxIters[, confidence]]]]]) -> retval, mask
cv.findHomography(srcPoints, dstPoints, params[, mask]) -> retval, mask

#include <opencv2/calib3d.hpp>

这是一个重载的成员函数,为方便起见而提供。它与上述函数的区别仅在于所接受的参数不同。

◆ getDefaultNewCameraMatrix()

Mat cv::getDefaultNewCameraMatrix ( InputArray cameraMatrix,
Size imgsize = Size(),
bool centerPrincipalPoint = false )
Python
cv.getDefaultNewCameraMatrix(cameraMatrix[, imgsize[, centerPrincipalPoint]]) -> retval

#include <opencv2/calib3d.hpp>

返回默认的新相机矩阵。

此函数返回相机矩阵,它或者是输入 cameraMatrix 的精确副本(当 centerPrinicipalPoint=false 时),或者是修改后的矩阵(当 centerPrincipalPoint=true 时)。

在后一种情况下,新的相机矩阵将是

\[\begin{bmatrix} f_x && 0 && ( \texttt{imgSize.width} -1)*0.5 \\ 0 && f_y && ( \texttt{imgSize.height} -1)*0.5 \\ 0 && 0 && 1 \end{bmatrix} ,\]

其中 \(f_x\) 和 \(f_y\) 分别是 cameraMatrix 的 \((0,0)\) 和 \((1,1)\) 元素。

默认情况下,OpenCV 中的去畸变函数(参见 initUndistortRectifyMapundistort)不会移动主点。然而,当处理立体图像时,将两个视图中的主点移动到相同的 y 坐标(大多数立体匹配算法都要求这样做),甚至可能移动到相同的 x 坐标,这很重要。因此,您可以为每个视图形成新的相机矩阵,其中主点位于中心。

参数
cameraMatrix输入相机矩阵。
imgsize相机视图图像的像素大小。
centerPrincipalPoint新相机矩阵中主点的位置。该参数指示此位置是否应位于图像中心。

◆ getOptimalNewCameraMatrix()

Mat cv::getOptimalNewCameraMatrix ( InputArray cameraMatrix,
InputArray distCoeffs,
Size imageSize,
double alpha,
Size newImgSize = Size(),
Rect * validPixROI = 0,
bool centerPrincipalPoint = false )
Python
cv.getOptimalNewCameraMatrix(cameraMatrix, distCoeffs, imageSize, alpha[, newImgSize[, centerPrincipalPoint]]) -> retval, validPixROI

#include <opencv2/calib3d.hpp>

基于自由缩放参数返回新的相机内参矩阵。

参数
cameraMatrix输入相机内参矩阵。
distCoeffs输入畸变系数向量 \(\distcoeffs\)。如果向量为 NULL/空,则假定畸变系数为零。
imageSize原始图像大小。
alpha自由缩放参数,介于 0(当去畸变图像中所有像素都有效时)和 1(当所有源图像像素都保留在去畸变图像中时)之间。有关详细信息,请参见 stereoRectify
newImgSize校正后的图像大小。默认情况下,它设置为 imageSize。
validPixROI可选输出矩形,概述去畸变图像中所有良好像素区域。请参见 stereoRectify 中 roi1, roi2 的描述。
centerPrincipalPoint可选标志,指示新相机内参矩阵中的主点是否应位于图像中心。默认情况下,主点被选择以最佳拟合源图像的子集(由 alpha 确定)到校正后的图像。
返回
new_camera_matrix 输出新相机内参矩阵。

该函数根据自由缩放参数计算并返回最佳新相机内参矩阵。通过改变此参数,您可以只检索有意义的像素 alpha=0,如果角落中有有价值的信息则保留所有原始图像像素 alpha=1,或者介于两者之间。当 alpha>0 时,去畸变结果可能会有一些黑色像素对应于捕获的畸变图像之外的“虚拟”像素。原始相机内参矩阵、畸变系数、计算出的新相机内参矩阵和 newImageSize 应传递给 initUndistortRectifyMap 以生成 remap 的映射。

◆ getValidDisparityROI()

Rect cv::getValidDisparityROI ( Rect roi1,
Rect roi2,
int minDisparity,
int numberOfDisparities,
int blockSize )
Python
cv.getValidDisparityROI(roi1, roi2, minDisparity, numberOfDisparities, blockSize) -> retval

#include <opencv2/calib3d.hpp>

从校正图像的有效 ROI(由 stereoRectify 返回)计算有效视差 ROI

◆ initCameraMatrix2D()

Mat cv::initCameraMatrix2D ( InputArrayOfArrays objectPoints,
InputArrayOfArrays imagePoints,
Size imageSize,
double aspectRatio = 1.0 )
Python
cv.initCameraMatrix2D(objectPoints, imagePoints, imageSize[, aspectRatio]) -> retval

#include <opencv2/calib3d.hpp>

从 3D-2D 点对应关系寻找初始相机内参矩阵。

参数
objectPoints校准模式点在校准模式坐标空间中的向量的向量。在旧接口中,所有每个视图的向量都串联在一起。有关详细信息,请参见 calibrateCamera
imagePoints校准模式点投影的向量的向量。在旧接口中,所有每个视图的向量都串联在一起。
imageSize用于初始化主点的像素图像大小。
aspectRatio如果为零或负,则 \(f_x\) 和 \(f_y\) 都独立估计。否则,\(f_x = f_y \cdot \texttt{aspectRatio}\)。

该函数估计并返回用于相机校准过程的初始相机内参矩阵。目前,该函数仅支持平面校准模式,即每个物体点 z 坐标为 0 的模式。

◆ initInverseRectificationMap()

void cv::initInverseRectificationMap ( InputArray cameraMatrix,
InputArray distCoeffs,
InputArray R,
InputArray newCameraMatrix,
const Size & size (大小),
int m1type,
OutputArray map1,
OutputArray map2 )
Python
cv.initInverseRectificationMap(cameraMatrix, distCoeffs, R, newCameraMatrix, size, m1type[, map1[, map2]]) -> map1, map2

#include <opencv2/calib3d.hpp>

计算投影和逆校正变换图。本质上,这是 initUndistortRectifyMap 的逆运算,用于适应投影仪-相机对中的投影仪(“逆相机”)的立体校正。

该函数计算联合投影和逆校正变换,并以 remap 映射的形式表示结果。投影图像看起来是原始图像的扭曲版本,一旦通过投影仪投影,应该在视觉上与原始图像匹配。在单目相机的情况下,newCameraMatrix 通常等于 cameraMatrix,或者可以通过 getOptimalNewCameraMatrix 计算以更好地控制缩放。在投影仪-相机对的情况下,newCameraMatrix 通常设置为由 stereoRectify 计算的 P1 或 P2。

投影仪根据 R 在坐标空间中以不同的方向定向。在投影仪-相机对的情况下,这有助于对齐投影仪(与 initUndistortRectifyMap 对相机的方式相同),以创建立体校正对。这使得两幅图像上的极线都变为水平并具有相同的 y 坐标(在水平对齐的投影仪-相机对的情况下)。

该函数为 remap 使用的逆映射算法构建映射。也就是说,对于目标(投影和逆校正)图像中的每个像素 \((u, v)\),该函数计算源图像(即原始数字图像)中对应的坐标。应用以下过程:

\[ \begin{array}{l} \text{newCameraMatrix}\\ x \leftarrow (u - {c'}_x)/{f'}_x \\ y \leftarrow (v - {c'}_y)/{f'}_y \\ \\\text{Undistortion} \\\scriptsize{\textit{尽管显示的方程用于径向去畸变,但函数实现了 cv::undistortPoints()}}\\ r^2 \leftarrow x^2 + y^2 \\ \theta \leftarrow \frac{1 + k_1 r^2 + k_2 r^4 + k_3 r^6}{1 + k_4 r^2 + k_5 r^4 + k_6 r^6}\\ x' \leftarrow \frac{x}{\theta} \\ y' \leftarrow \frac{y}{\theta} \\ \\\text{Rectification}\\ {[X\,Y\,W]} ^T \leftarrow R*[x' \, y' \, 1]^T \\ x'' \leftarrow X/W \\ y'' \leftarrow Y/W \\ \\\text{cameraMatrix}\\ map_x(u,v) \leftarrow x'' f_x + c_x \\ map_y(u,v) \leftarrow y'' f_y + c_y \end{array} \]

其中 \((k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6[, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]])\) 是畸变系数向量 distCoeffs。

在立体校正的投影仪-相机对的情况下,该函数用于投影仪,而 initUndistortRectifyMap 用于相机头。这是在 stereoRectify 之后完成的,后者又在 stereoCalibrate 之后完成。如果投影仪-相机对未校准,仍然可以直接从基础矩阵使用 stereoRectifyUncalibrated 计算校正变换。对于投影仪和相机,该函数计算单应性 H 作为像素域中的校正变换,而不是 3D 空间中的旋转矩阵 R。R 可以从 H 计算为

\[\texttt{R} = \texttt{cameraMatrix} ^{-1} \cdot \texttt{H} \cdot \texttt{cameraMatrix}\]

其中 cameraMatrix 可以任意选择。

参数
cameraMatrix输入相机矩阵 \(A=\vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\)。
distCoeffs畸变系数向量 \((k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6[, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]])\),包含 4、5、8、12 或 14 个元素。如果向量为 NULL/空,则假定畸变系数为零。
R对象空间中的可选校正变换(3x3 矩阵)。这里可以传递由 stereoRectify 计算的 R1 或 R2。如果矩阵为空,则假定为单位变换。
newCameraMatrix新的相机矩阵 \(A'=\vecthreethree{f_x'}{0}{c_x'}{0}{f_y'}{c_y'}{0}{0}{1}\)。
size (大小)畸变图像大小。
m1type第一个输出映射的类型。可以是 CV_32FC1, CV_32FC2 或 CV_16SC2,请参见 convertMaps
map1remap 的第一个输出映射。
map2remap 的第二个输出映射。

◆ initUndistortRectifyMap()

void cv::initUndistortRectifyMap ( InputArray cameraMatrix,
InputArray distCoeffs,
InputArray R,
InputArray newCameraMatrix,
Size size (大小),
int m1type,
OutputArray map1,
OutputArray map2 )
Python
cv.initUndistortRectifyMap(cameraMatrix, distCoeffs, R, newCameraMatrix, size, m1type[, map1[, map2]]) -> map1, map2

#include <opencv2/calib3d.hpp>

计算去畸变和校正变换映射。

该函数计算联合去畸变和校正变换,并以 remap 映射的形式表示结果。去畸变图像看起来像原始图像,就好像它是用相机矩阵 =newCameraMatrix 和零畸变捕获的。在单目相机的情况下,newCameraMatrix 通常等于 cameraMatrix,或者可以通过 getOptimalNewCameraMatrix 计算以更好地控制缩放。在立体相机的情况下,newCameraMatrix 通常设置为由 stereoRectify 计算的 P1 或 P2。

此外,这个新相机在坐标空间中的方向也不同,根据 R。例如,这有助于对齐立体相机的两个头部,使得两幅图像上的极线都变为水平并具有相同的 y 坐标(在水平对齐的立体相机的情况下)。

该函数实际上为 remap 使用的逆映射算法构建映射。也就是说,对于目标(校正和校正)图像中的每个像素 \((u, v)\),该函数计算源图像(即来自相机的原始图像)中对应的坐标。应用以下过程:

\[ \begin{array}{l} x \leftarrow (u - {c'}_x)/{f'}_x \\ y \leftarrow (v - {c'}_y)/{f'}_y \\ {[X\,Y\,W]} ^T \leftarrow R^{-1}*[x \, y \, 1]^T \\ x' \leftarrow X/W \\ y' \leftarrow Y/W \\ r^2 \leftarrow x'^2 + y'^2 \\ x'' \leftarrow x' \frac{1 + k_1 r^2 + k_2 r^4 + k_3 r^6}{1 + k_4 r^2 + k_5 r^4 + k_6 r^6} + 2p_1 x' y' + p_2(r^2 + 2 x'^2) + s_1 r^2 + s_2 r^4\\ y'' \leftarrow y' \frac{1 + k_1 r^2 + k_2 r^4 + k_3 r^6}{1 + k_4 r^2 + k_5 r^4 + k_6 r^6} + p_1 (r^2 + 2 y'^2) + 2 p_2 x' y' + s_3 r^2 + s_4 r^4 \\ s\vecthree{x'''}{y'''}{1} = \vecthreethree{R_{33}(\tau_x, \tau_y)}{0}{-R_{13}((\tau_x, \tau_y)} {0}{R_{33}(\tau_x, \tau_y)}{-R_{23}(\tau_x, \tau_y)} {0}{0}{1} R(\tau_x, \tau_y) \vecthree{x''}{y''}{1}\\ map_x(u,v) \leftarrow x''' f_x + c_x \\ map_y(u,v) \leftarrow y''' f_y + c_y \end{array} \]

其中 \((k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6[, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]])\) 是畸变系数。

在立体相机的情况下,该函数被调用两次:在 stereoRectify 之后,每个相机头一次,而 stereoRectify 又在 stereoCalibrate 之后调用。但是,如果立体相机未校准,仍然可以直接从基础矩阵使用 stereoRectifyUncalibrated 计算校正变换。对于每个相机,该函数计算单应性 H 作为像素域中的校正变换,而不是 3D 空间中的旋转矩阵 R。R 可以从 H 计算为

\[\texttt{R} = \texttt{cameraMatrix} ^{-1} \cdot \texttt{H} \cdot \texttt{cameraMatrix}\]

其中 cameraMatrix 可以任意选择。

参数
cameraMatrix输入相机矩阵 \(A=\vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\)。
distCoeffs畸变系数向量 \((k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6[, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]])\),包含 4、5、8、12 或 14 个元素。如果向量为 NULL/空,则假定畸变系数为零。
R对象空间中的可选校正变换(3x3 矩阵)。这里可以传递由 stereoRectify 计算的 R1 或 R2。如果矩阵为空,则假定为单位变换。在 initUndistortRectifyMap 中,R 假定为单位矩阵。
newCameraMatrix新的相机矩阵 \(A'=\vecthreethree{f_x'}{0}{c_x'}{0}{f_y'}{c_y'}{0}{0}{1}\)。
size (大小)去畸变图像的大小。
m1type第一个输出映射的类型,可以是 CV_32FC1, CV_32FC2 或 CV_16SC2,请参见 convertMaps
map1第一个输出映射。
map2第二个输出映射。

◆ initWideAngleProjMap() [1/2]

float cv::initWideAngleProjMap ( InputArray cameraMatrix,
InputArray distCoeffs,
Size imageSize,
int destImageWidth,
int m1type,
OutputArray map1,
OutputArray map2,
enum UndistortTypes projType = PROJ_SPHERICAL_EQRECT,
double alpha = 0 )

#include <opencv2/calib3d.hpp>

初始化用于广角图像 remap 的映射。

◆ initWideAngleProjMap() [2/2]

static float cv::initWideAngleProjMap ( InputArray cameraMatrix,
InputArray distCoeffs,
Size imageSize,
int destImageWidth,
int m1type,
OutputArray map1,
OutputArray map2,
int projType,
double alpha = 0 )
inlinestatic

#include <opencv2/calib3d.hpp>

此函数的调用图

◆ matMulDeriv()

void cv::matMulDeriv ( InputArray A,
InputArray B,
OutputArray dABdA,
OutputArray dABdB )
Python
cv.matMulDeriv(A, B[, dABdA[, dABdB]]) -> dABdA, dABdB

#include <opencv2/calib3d.hpp>

针对相乘的每个矩阵计算矩阵乘积的偏导数。

参数
A第一个相乘矩阵。
B第二个相乘矩阵。
dABdA第一个输出导数矩阵 d(A*B)/dA,大小为 \(\texttt{A.rows*B.cols} \times {A.rows*A.cols}\)。
dABdB第二个输出导数矩阵 d(A*B)/dB,大小为 \(\texttt{A.rows*B.cols} \times {B.rows*B.cols}\)。

该函数计算矩阵乘积 \(A*B\) 元素的偏导数,相对于两个输入矩阵的每个元素。该函数用于计算 stereoCalibrate 中的雅可比矩阵,但也可用于任何其他类似的优化函数。

◆ projectPoints()

void cv::projectPoints ( InputArray objectPoints,
InputArray rvec,
InputArray tvec,
InputArray cameraMatrix,
InputArray distCoeffs,
OutputArray imagePoints,
OutputArray jacobian = noArray(),
double aspectRatio = 0 )
Python
cv.projectPoints(objectPoints, rvec, tvec, cameraMatrix, distCoeffs[, imagePoints[, jacobian[, aspectRatio]]]) -> imagePoints, jacobian

#include <opencv2/calib3d.hpp>

将 3D 点投影到图像平面。

参数
objectPoints在世界坐标系中表示的对象点数组。一个 3xN/Nx3 1 通道或 1xN/Nx1 3 通道(或 vector<Point3f>),其中 N 是视图中的点数。
rvec旋转向量(Rodrigues),与 tvec 一起执行从世界坐标系到相机坐标系的基变换,详情请参阅 calibrateCamera
tvec平移向量,请参阅上面参数描述。
cameraMatrix相机内参矩阵 \(\cameramatrix{A}\)。
distCoeffs输入畸变系数向量 \(\distcoeffs\)。如果向量为空,则假定为零畸变系数。
imagePoints图像点输出数组,1xN/Nx1 2 通道,或 vector<Point2f>。
jacobian可选输出 2Nx(10+<numDistCoeffs>) 雅可比矩阵,包含图像点对旋转向量、平移向量、焦距、主点坐标和畸变系数的偏导数。在旧接口中,雅可比矩阵的不同分量通过不同的输出参数返回。
aspectRatio可选的“固定纵横比”参数。如果参数不为 0,则函数假定纵横比(\(f_x / f_y\))是固定的,并相应地调整雅可比矩阵。

该函数根据相机内参和外参,计算 3D 点到图像平面的 2D 投影。可选地,该函数计算雅可比矩阵——图像点坐标(作为所有输入参数的函数)对特定参数(内参和/或外参)的偏导数矩阵。雅可比矩阵用于 calibrateCamerasolvePnPstereoCalibrate 中的全局优化。该函数本身也可用于计算重投影误差,给定当前的内参和外参。

注意
通过设置 rvec = tvec = \([0, 0, 0]\),或者将 cameraMatrix 设置为 3x3 单位矩阵,或者传递零畸变系数,可以得到该函数的各种有用偏例。这意味着,可以在理想的零畸变设置中计算稀疏点集的畸变坐标或应用透视变换(并计算导数)。

◆ recoverPose() [1/4]

int cv::recoverPose ( InputArray E,
InputArray points1,
InputArray points2,
InputArray cameraMatrix,
OutputArray R,
OutputArray t,
double distanceThresh,
InputOutputArray mask = noArray(),
OutputArray triangulatedPoints = noArray() )
Python
cv.recoverPose(points1, points2, cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2[, E[, R[, t[, method[, prob[, threshold[, mask]]]]]]]) -> retval, E, R, t, mask
cv.recoverPose(E, points1, points2, cameraMatrix[, R[, t[, mask]]]) -> retval, R, t, mask
cv.recoverPose(E, points1, points2[, R[, t[, focal[, pp[, mask]]]]]) -> retval, R, t, mask
cv.recoverPose(E, points1, points2, cameraMatrix, distanceThresh[, R[, t[, mask[, triangulatedPoints]]]]) -> retval, R, t, mask, triangulatedPoints

#include <opencv2/calib3d.hpp>

这是一个重载的成员函数,为方便起见而提供。它与上述函数的区别仅在于所接受的参数不同。

参数
E输入的本质矩阵。
points1来自第一张图像的 N 个 2D 点的数组。点坐标应为浮点数(单精度或双精度)。
points2第二幅图像中的点数组,与 points1 大小和格式相同。
cameraMatrix相机内参矩阵 \(\cameramatrix{A}\)。请注意,此函数假定 points1 和 points2 是来自具有相同相机内参矩阵的相机的特征点。
R输出旋转矩阵。与平移向量一起,此矩阵构成一个元组,执行从第一个相机坐标系到第二个相机坐标系的基变换。请注意,通常情况下,t 不能用于此元组,请参阅下面的参数描述。
t输出平移向量。此向量通过 decomposeEssentialMat 获得,因此仅已知其尺度,即 t 是平移向量的方向,并且具有单位长度。
distanceThresh用于过滤掉远处点(即无限点)的阈值距离。
maskpoints1 和 points2 中内点的输入/输出掩码。如果它不为空,则它标记给定基本矩阵 E 的 points1 和 points2 中的内点。只有这些内点将用于恢复姿态。在输出掩码中,只有通过手性检查的内点。
triangulatedPoints通过三角测量重建的 3D 点。

此函数与上述函数不同,它输出用于手性检查的三角测量 3D 点。

◆ recoverPose() [2/4]

int cv::recoverPose ( InputArray E,
InputArray points1,
InputArray points2,
InputArray cameraMatrix,
OutputArray R,
OutputArray t,
InputOutputArray mask = noArray() )
Python
cv.recoverPose(points1, points2, cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2[, E[, R[, t[, method[, prob[, threshold[, mask]]]]]]]) -> retval, E, R, t, mask
cv.recoverPose(E, points1, points2, cameraMatrix[, R[, t[, mask]]]) -> retval, R, t, mask
cv.recoverPose(E, points1, points2[, R[, t[, focal[, pp[, mask]]]]]) -> retval, R, t, mask
cv.recoverPose(E, points1, points2, cameraMatrix, distanceThresh[, R[, t[, mask[, triangulatedPoints]]]]) -> retval, R, t, mask, triangulatedPoints

#include <opencv2/calib3d.hpp>

根据估算的本质矩阵和两幅图像中的对应点,通过手性检查(chirality check)恢复相机的相对旋转和平移。返回通过检查的内点数量。

参数
E输入的本质矩阵。
points1来自第一张图像的 N 个 2D 点的数组。点坐标应为浮点数(单精度或双精度)。
points2第二幅图像中的点数组,与 points1 大小和格式相同。
cameraMatrix相机内参矩阵 \(\cameramatrix{A}\)。请注意,此函数假定 points1 和 points2 是来自具有相同相机内参矩阵的相机的特征点。
R输出旋转矩阵。与平移向量一起,此矩阵构成一个元组,执行从第一个相机坐标系到第二个相机坐标系的基变换。请注意,通常情况下,t 不能用于此元组,请参阅下面描述的参数。
t输出平移向量。此向量通过 decomposeEssentialMat 获得,因此仅已知其尺度,即 t 是平移向量的方向,并且具有单位长度。
maskpoints1 和 points2 中内点的输入/输出掩码。如果它不为空,则它标记给定基本矩阵 E 的 points1 和 points2 中的内点。只有这些内点将用于恢复姿态。在输出掩码中,只有通过手性检查的内点。

此函数使用 decomposeEssentialMat 分解基本矩阵,然后通过手性检查验证可能的姿态假设。手性检查意味着三角测量的 3D 点应具有正深度。有关详细信息,请参见 [214]

此函数可用于处理来自 findEssentialMat 的输出 E 和 mask。在这种情况下,points1 和 points2 是 findEssentialMat 的相同输入。

// 示例。使用 RANSAC 算法估计基本矩阵
int point_count = 100;
vector<Point2f> points1(point_count);
vector<Point2f> points2(point_count);
// 在此处初始化点...
for( int i = 0; i < point_count; i++ )
{
points1[i] = ...;
points2[i] = ...;
}
// 焦距均为 1,主点为 (0, 0) 的相机矩阵
Mat cameraMatrix = Mat::eye(3, 3, CV_64F);
Mat E, R, t, mask;
E = findEssentialMat(points1, points2, cameraMatrix, RANSAC, 0.999, 1.0, mask);
recoverPose(E, points1, points2, cameraMatrix, R, t, mask);
static CV_NODISCARD_STD MatExpr eye(int rows, int cols, int type)
返回指定大小和类型的单位矩阵。
int recoverPose(InputArray points1, InputArray points2, InputArray cameraMatrix1, InputArray distCoeffs1, InputArray cameraMatrix2, InputArray distCoeffs2, OutputArray E, OutputArray R, OutputArray t, int method=cv::RANSAC, double prob=0.999, double threshold=1.0, InputOutputArray mask=noArray())
从两幅图像中对应的点恢复相对相机旋转和平移…
Mat findEssentialMat(InputArray points1, InputArray points2, InputArray cameraMatrix, int method=RANSAC, double prob=0.999, double threshold=1.0, int maxIters=1000, OutputArray mask=noArray())
根据两幅图像中的对应点计算本质矩阵。
@ RANSAC
RANSAC算法。
定义 calib3d.hpp:552
#define CV_64F
定义位于 interface.h:79

◆ recoverPose() [3/4]

int cv::recoverPose ( InputArray E,
InputArray points1,
InputArray points2,
OutputArray R,
OutputArray t,
double focal = 1.0,
Point2d pp = Point2d(0, 0),
InputOutputArray mask = noArray() )
Python
cv.recoverPose(points1, points2, cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2[, E[, R[, t[, method[, prob[, threshold[, mask]]]]]]]) -> retval, E, R, t, mask
cv.recoverPose(E, points1, points2, cameraMatrix[, R[, t[, mask]]]) -> retval, R, t, mask
cv.recoverPose(E, points1, points2[, R[, t[, focal[, pp[, mask]]]]]) -> retval, R, t, mask
cv.recoverPose(E, points1, points2, cameraMatrix, distanceThresh[, R[, t[, mask[, triangulatedPoints]]]]) -> retval, R, t, mask, triangulatedPoints

#include <opencv2/calib3d.hpp>

这是一个重载的成员函数,为方便起见而提供。它与上述函数的区别仅在于所接受的参数不同。

参数
E输入的本质矩阵。
points1来自第一张图像的 N 个 2D 点的数组。点坐标应为浮点数(单精度或双精度)。
points2第二幅图像中的点数组,与 points1 大小和格式相同。
R输出旋转矩阵。与平移向量一起,此矩阵构成一个元组,执行从第一个相机坐标系到第二个相机坐标系的基变换。请注意,通常情况下,t 不能用于此元组,请参阅下面的参数描述。
t输出平移向量。此向量通过 decomposeEssentialMat 获得,因此仅已知其尺度,即 t 是平移向量的方向,并且具有单位长度。
focal相机焦距。请注意,此函数假定 points1 和 points2 是来自具有相同焦距和主点的相机的特征点。
pp相机主点。
maskpoints1 和 points2 中内点的输入/输出掩码。如果它不为空,则它标记给定基本矩阵 E 的 points1 和 points2 中的内点。只有这些内点将用于恢复姿态。在输出掩码中,只有通过手性检查的内点。

此函数与上面一个不同,它从焦距和主点计算相机内部矩阵。

\[A = \begin{bmatrix} f & 0 & x_{pp} \\ 0 & f & y_{pp} \\ 0 & 0 & 1 \end{bmatrix}\]

◆ recoverPose() [4/4]

int cv::recoverPose ( InputArray points1,
InputArray points2,
InputArray cameraMatrix1,
InputArray distCoeffs1,
InputArray cameraMatrix2,
InputArray distCoeffs2,
OutputArray E,
OutputArray R,
OutputArray t,
int method = cv::RANSAC,
double prob = 0.999,
double threshold = 1.0,
InputOutputArray mask = noArray() )
Python
cv.recoverPose(points1, points2, cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2[, E[, R[, t[, method[, prob[, threshold[, mask]]]]]]]) -> retval, E, R, t, mask
cv.recoverPose(E, points1, points2, cameraMatrix[, R[, t[, mask]]]) -> retval, R, t, mask
cv.recoverPose(E, points1, points2[, R[, t[, focal[, pp[, mask]]]]]) -> retval, R, t, mask
cv.recoverPose(E, points1, points2, cameraMatrix, distanceThresh[, R[, t[, mask[, triangulatedPoints]]]]) -> retval, R, t, mask, triangulatedPoints

#include <opencv2/calib3d.hpp>

利用手性检查(cheirality check),从两台不同相机的两幅图像中的对应点恢复相机的相对旋转和平移。返回通过检查的内点(inliers)数量。

参数
points1来自第一张图像的 N 个 2D 点的数组。点坐标应为浮点数(单精度或双精度)。
points2第二幅图像中的点数组,与 points1 大小和格式相同。
cameraMatrix1第一个相机的输入/输出相机矩阵,与 calibrateCamera 中相同。此外,对于立体情况,可以使用额外的标志,请参阅下文。
distCoeffs1输入/输出畸变系数向量,与 calibrateCamera 中相同。
cameraMatrix2第一个相机的输入/输出相机矩阵,与 calibrateCamera 中相同。此外,对于立体情况,可以使用额外的标志,请参阅下文。
distCoeffs2输入/输出畸变系数向量,与 calibrateCamera 中相同。
E输出基本矩阵。
R输出旋转矩阵。与平移向量一起,此矩阵构成一个元组,执行从第一个相机坐标系到第二个相机坐标系的基变换。请注意,通常情况下,t 不能用于此元组,请参阅下面描述的参数。
t输出平移向量。此向量通过 decomposeEssentialMat 获得,因此仅已知其尺度,即 t 是平移向量的方向,并且具有单位长度。
method计算本质矩阵的方法。
  • RANSAC 用于 RANSAC 算法。
  • LMEDS 用于 LMedS 算法。
prob仅用于 RANSAC 或 LMedS 方法的参数。它指定了估计矩阵正确的期望置信度(概率)。
阈值 (threshold)RANSAC 参数。它是从点到对极线在像素中的最大距离,超出此距离的点被视为离群点,不用于计算最终的基本矩阵。可以设置为 1-3 左右,具体取决于点定位的精度、图像分辨率和图像噪声。
maskpoints1 和 points2 中内点的输入/输出掩码。如果它不为空,则它标记给定基本矩阵 E 的 points1 和 points2 中的内点。只有这些内点将用于恢复姿态。在输出掩码中,只有通过手性检查的内点。

此函数使用 decomposeEssentialMat 分解基本矩阵,然后通过手性检查验证可能的姿态假设。手性检查意味着三角测量的 3D 点应具有正深度。有关详细信息,请参见 [214]

此函数可用于处理来自 findEssentialMat 的输出 E 和 mask。在这种情况下,points1 和 points2 是 findEssentialMat 的相同输入。

// 示例。使用 RANSAC 算法估计基本矩阵
int point_count = 100;
vector<Point2f> points1(point_count);
vector<Point2f> points2(point_count);
// 在此处初始化点...
for( int i = 0; i < point_count; i++ )
{
points1[i] = ...;
points2[i] = ...;
}
// 输入:两个相机的相机校准,例如使用内部棋盘校准。
Mat cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2;
// 输出:基本矩阵、相对旋转和相对平移。
Mat E, R, t, mask;
recoverPose(points1, points2, cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2, E, R, t, mask);

◆ rectify3Collinear()

float cv::rectify3Collinear ( InputArray cameraMatrix1,
InputArray distCoeffs1,
InputArray cameraMatrix2,
InputArray distCoeffs2,
InputArray cameraMatrix3,
InputArray distCoeffs3,
InputArrayOfArrays imgpt1,
InputArrayOfArrays imgpt3,
Size imageSize,
InputArray R12,
InputArray T12,
InputArray R13,
InputArray T13,
OutputArray R1,
OutputArray R2,
OutputArray R3,
OutputArray P1,
OutputArray P2,
OutputArray P3,
OutputArray Q,
double alpha,
Size newImgSize,
Rect * roi1,
Rect * roi2,
int flags (标志) )
Python
cv.rectify3Collinear(cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2, cameraMatrix3, distCoeffs3, imgpt1, imgpt3, imageSize, R12, T12, R13, T13, alpha, newImgSize, flags[, R1[, R2[, R3[, P1[, P2[, P3[, Q]]]]]]]) -> retval, R1, R2, R3, P1, P2, P3, Q, roi1, roi2

#include <opencv2/calib3d.hpp>

计算三头相机的校正变换,其中所有相机头都在同一直线上。

◆ reprojectImageTo3D()

void cv::reprojectImageTo3D ( InputArray disparity,
OutputArray _3dImage,
InputArray Q,
bool handleMissingValues = false,
int ddepth = -1 )
Python
cv.reprojectImageTo3D(disparity, Q[, _3dImage[, handleMissingValues[, ddepth]]]) -> _3dImage

#include <opencv2/calib3d.hpp>

将视差图像重新投影到 3D 空间。

参数
disparity输入单通道 8 位无符号、16 位有符号、32 位有符号或 32 位浮点视差图像。8 位/16 位有符号格式的值假定没有小数位。如果视差是 16 位有符号格式,如由 StereoBMStereoSGBM 以及其他算法计算的,它在使用前应除以 16(并缩放到浮点数)。
_3dImage输出 3 通道浮点图像,与视差图像大小相同。_3dImage(x,y) 的每个元素包含从视差图计算的点 (x,y) 的 3D 坐标。如果使用 stereoRectify 获得的 Q,则返回的点以第一个相机的校正坐标系表示。
Q可以通过 stereoRectify 获得的 \(4 \times 4\) 透视变换矩阵。
handleMissingValues指示函数是否应处理缺失值(即未计算视差的点)。如果 handleMissingValues=true,则对应于异常值(参见 StereoMatcher::compute)的最小视差像素将转换为具有非常大 Z 值(当前设置为 10000)的 3D 点。
ddepth可选输出数组深度。如果为 -1,则输出图像将具有 CV_32F 深度。ddepth 也可以设置为 CV_16S、CV_32S 或 CV_32F。

该函数将单通道视差图转换为表示 3D 表面的 3 通道图像。也就是说,对于每个像素 (x,y) 及其对应的视差 d=disparity(x,y),它计算:

\[\begin{bmatrix} X \\ Y \\ Z \\ W \end{bmatrix} = Q \begin{bmatrix} x \\ y \\ \texttt{disparity} (x,y) \\ 1 \end{bmatrix}.\]

另请参阅
要将稀疏点集 \({(x,y,d),...}\) 重投影到 3D 空间,请使用 perspectiveTransform

◆ Rodrigues()

void cv::Rodrigues ( InputArray src,
OutputArray dst,
OutputArray jacobian = noArray() )
Python
cv.Rodrigues(src[, dst[, jacobian]]) -> dst, jacobian

#include <opencv2/calib3d.hpp>

在旋转矩阵与旋转向量之间进行转换。

参数
src输入旋转向量(3x1 或 1x3)或旋转矩阵(3x3)。
dst输出旋转矩阵(3x3)或旋转向量(3x1 或 1x3),分别。
jacobian可选输出雅可比矩阵,3x9 或 9x3,它是输出数组分量对输入数组分量的偏导数矩阵。

\[\begin{array}{l} \theta \leftarrow norm(r) \\ r \leftarrow r/ \theta \\ R = \cos(\theta) I + (1- \cos{\theta} ) r r^T + \sin(\theta) \vecthreethree{0}{-r_z}{r_y}{r_z}{0}{-r_x}{-r_y}{r_x}{0} \end{array}\]

逆变换也可以轻松完成,因为

\[\sin ( \theta ) \vecthreethree{0}{-r_z}{r_y}{r_z}{0}{-r_x}{-r_y}{r_x}{0} = \frac{R - R^T}{2}\]

旋转向量是旋转矩阵的一种方便且最紧凑的表示(因为任何旋转矩阵只有 3 个自由度)。该表示用于全局 3D 几何优化过程,如 calibrateCamerastereoCalibratesolvePnP

注意
有关 3D 旋转矩阵对其指数坐标导数计算的更多信息,请参见
  • 《三维旋转指数坐标导数的紧凑公式》,Guillermo Gallego, Anthony J. Yezzi [100]
有关 SE(3) 和李群的有用信息,请参见
  • 《SE(3) 变换参数化和流形优化教程》,Jose-Luis Blanco [31]
  • 《2D 和 3D 变换的李群》,Ethan Eade [82]
  • 《机器人状态估计的微李理论》,Joan Solà, Jérémie Deray, Dinesh Atchuthan [255]

◆ RQDecomp3x3()

Vec3d cv::RQDecomp3x3 ( InputArray src,
OutputArray mtxR,
OutputArray mtxQ,
OutputArray Qx = noArray(),
OutputArray Qy = noArray(),
OutputArray Qz = noArray() )
Python
cv.RQDecomp3x3(src[, mtxR[, mtxQ[, Qx[, Qy[, Qz]]]]]) -> retval, mtxR, mtxQ, Qx, Qy, Qz

#include <opencv2/calib3d.hpp>

计算 3x3 矩阵的 RQ 分解。

参数
src3x3 输入矩阵。
mtxR输出 3x3 上三角矩阵。
mtxQ输出 3x3 正交矩阵。
Qx可选输出 3x3 绕 x 轴旋转矩阵。
Qy可选输出 3x3 绕 y 轴旋转矩阵。
Qz可选输出 3x3 绕 z 轴旋转矩阵。

该函数使用给定的旋转计算 RQ 分解。该函数用于 decomposeProjectionMatrix 将投影矩阵的左上角 3x3 子矩阵分解为相机和旋转矩阵。

它可选地返回三个旋转矩阵,每个轴一个,以及三个以度为单位的欧拉角(作为返回值),可用于 OpenGL。请注意,始终存在不止一种围绕三个主轴的旋转序列,可以产生相同的对象方向,例如参见 [254]。返回的三个旋转矩阵和相应的三个欧拉角只是可能的解决方案之一。

◆ sampsonDistance()

double cv::sampsonDistance ( InputArray pt1,
InputArray pt2,
InputArray F )
Python
cv.sampsonDistance(pt1, pt2, F) -> retval

#include <opencv2/calib3d.hpp>

计算两点之间的 Sampson 距离。

函数 cv::sampsonDistance 计算并返回几何误差的一阶近似值:

\[ sd( \texttt{pt1} , \texttt{pt2} )= \frac{(\texttt{pt2}^t \cdot \texttt{F} \cdot \texttt{pt1})^2} {((\texttt{F} \cdot \texttt{pt1})(0))^2 + ((\texttt{F} \cdot \texttt{pt1})(1))^2 + ((\texttt{F}^t \cdot \texttt{pt2})(0))^2 + ((\texttt{F}^t \cdot \texttt{pt2})(1))^2} \]

基础矩阵可以使用 findFundamentalMat 函数计算。详情请参阅 [120] 11.4.3。

参数
pt1第一个齐次 2d 点
pt2第二个齐次 2d 点
F基本矩阵
返回
计算出的 Sampson 距离。

◆ solveP3P()

int cv::solveP3P ( InputArray objectPoints,
InputArray imagePoints,
InputArray cameraMatrix,
InputArray distCoeffs,
OutputArrayOfArrays rvecs,
OutputArrayOfArrays tvecs,
int flags (标志) )
Python
cv.solveP3P(objectPoints, imagePoints, cameraMatrix, distCoeffs, flags[, rvecs[, tvecs]]) -> retval, rvecs, tvecs

#include <opencv2/calib3d.hpp>

3 组 3D-2D 点对应关系中寻找物体姿态 \( {}^{c}\mathbf{T}_o \)。

透视投影,从对象帧到相机帧
另请参阅
透视-n-点 (PnP) 姿态计算
参数
objectPoints物体坐标空间中的物体点数组,3x3 1 通道或 1x3/3x1 3 通道。这里也可以传递 vector<Point3f>。
imagePoints对应的图像点数组,3x2 1 通道或 1x3/3x1 2 通道。这里也可以传递 vector<Point2f>。
cameraMatrix输入相机内参矩阵 \(\cameramatrix{A}\)。
distCoeffs输入畸变系数向量 \(\distcoeffs\)。如果向量为 NULL/空,则假定畸变系数为零。
rvecs输出旋转向量(参见 Rodrigues),与 tvecs 一起将点从模型坐标系转换到相机坐标系。P3P 问题最多有 4 个解。
tvecs输出平移向量。
flags (标志)求解 P3P 问题的方法
  • SOLVEPNP_P3P 方法基于 Ding, Y., Yang, J., Larsson, V., Olsson, C., & Åstrom, K. "Revisiting the P3P Problem" ([73]) 的论文。
  • SOLVEPNP_AP3P 方法基于 T. Ke 和 S. Roumeliotis. "An Efficient Algebraic Solution to the Perspective-Three-Point Problem" ([150]) 的论文。

该函数根据给定的 3 个物体点、它们对应的图像投影以及相机内参矩阵和畸变系数来估计物体姿态。

注意
解决方案按重投影误差排序(从低到高)。

◆ solvePnP()

bool cv::solvePnP ( InputArray objectPoints,
InputArray imagePoints,
InputArray cameraMatrix,
InputArray distCoeffs,
OutputArray rvec,
OutputArray tvec,
bool useExtrinsicGuess = false,
int flags = SOLVEPNP_ITERATIVE )
Python
cv.solvePnP(objectPoints, imagePoints, cameraMatrix, distCoeffs[, rvec[, tvec[, useExtrinsicGuess[, flags]]]]) -> retval, rvec, tvec

#include <opencv2/calib3d.hpp>

从 3D-2D 点对应关系中寻找物体姿态 \( {}^{c}\mathbf{T}_o \)

透视投影,从对象帧到相机帧
另请参阅
透视-n-点 (PnP) 姿态计算

该函数使用不同的方法返回将对象坐标系中表示的 3D 点转换为相机坐标系的旋转和平移向量。

  • P3P 方法(SOLVEPNP_P3PSOLVEPNP_AP3P):需要 4 个输入点才能返回唯一解。
  • SOLVEPNP_IPPE 输入点必须 >= 4 且对象点必须共面。
  • 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,且对象点可以是任何配置。
参数
objectPoints对象坐标空间中的对象点数组,Nx3 1 通道或 1xN/Nx1 3 通道,其中 N 是点数。这里也可以传递 vector<Point3d>。
imagePoints对应的图像点数组,Nx2 1 通道或 1xN/Nx1 2 通道,其中 N 是点数。这里也可以传递 vector<Point2d>。
cameraMatrix输入相机内参矩阵 \(\cameramatrix{A}\)。
distCoeffs输入畸变系数向量 \(\distcoeffs\)。如果向量为 NULL/空,则假定畸变系数为零。
rvec输出旋转向量(参见 Rodrigues),与 tvec 一起将点从模型坐标系转换到相机坐标系。
tvec输出平移向量。
useExtrinsicGuess用于 SOLVEPNP_ITERATIVE 的参数。如果为 true (1),则函数使用提供的 rvec 和 tvec 值作为旋转和平移向量的初始近似值,并进一步优化它们。
flags (标志)解决 PnP 问题的方法:参见 calib3d_solvePnP_flags

有关 Perspective-n-Points 的更多信息,请参见 Perspective-n-Point (PnP) 姿态计算

注意
  • 如何在平面增强现实中使用 solvePnP 的示例可以在 opencv_source_code/samples/python/plane_ar.py 中找到。
  • 如果您正在使用 Python
    • Numpy 数组切片不能作为输入,因为 solvePnP 需要连续数组(由 modules/calib3d/src/solvepnp.cpp 版本 2.4.9 第 55 行左右的 cv::Mat::checkVector() 断言强制执行)。
    • P3P 算法要求图像点为形状 (N,1,2) 的数组,因为它调用了 undistortPoints(modules/calib3d/src/solvepnp.cpp 版本 2.4.9 第 75 行左右),该函数需要 2 通道信息。
    • 因此,给定一些数据 D = np.array(...),其中 D.shape = (N,M),为了将其子集用作(例如)imagePoints,必须将其有效地复制到一个新数组中:imagePoints = np.ascontiguousarray(D[:,:2]).reshape((N,1,2))
  • 方法 SOLVEPNP_DLSSOLVEPNP_UPNP 不能使用,因为当前的实现不稳定,有时会给出完全错误的结果。如果您传递这两个标志中的一个,将改用 SOLVEPNP_EPNP 方法。
  • 在一般情况下,最小点数为 4。对于 SOLVEPNP_P3PSOLVEPNP_AP3P 方法,需要精确使用 4 个点(前 3 个点用于估计 P3P 问题的所有解,最后一个点用于保留最小化重投影误差的最佳解)。
  • 使用 SOLVEPNP_ITERATIVE 方法且 useExtrinsicGuess=true 时,最小点数为 3(3 个点足以计算姿态,但最多有 4 个解)。初始解应接近全局解才能收敛。如果找到某个解,函数返回 true。用户代码负责评估解的质量。
  • 使用 SOLVEPNP_IPPE 输入点必须 >= 4 且对象点必须共面。
  • 使用 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]
  • 使用 SOLVEPNP_SQPNP 输入点必须 >= 3

◆ solvePnPGeneric()

int cv::solvePnPGeneric ( InputArray objectPoints,
InputArray imagePoints,
InputArray cameraMatrix,
InputArray distCoeffs,
OutputArrayOfArrays rvecs,
OutputArrayOfArrays tvecs,
bool useExtrinsicGuess = false,
SolvePnPMethod flags = SOLVEPNP_ITERATIVE,
InputArray rvec = noArray(),
InputArray tvec = noArray(),
OutputArray reprojectionError = noArray() )
Python
cv.solvePnPGeneric(objectPoints, imagePoints, cameraMatrix, distCoeffs[, rvecs[, tvecs[, useExtrinsicGuess[, flags[, rvec[, tvec[, reprojectionError]]]]]]]) -> retval, rvecs, tvecs, reprojectionError

#include <opencv2/calib3d.hpp>

从 3D-2D 点对应关系中寻找物体姿态 \( {}^{c}\mathbf{T}_o \)。

透视投影,从对象帧到相机帧
另请参阅
透视-n-点 (PnP) 姿态计算

此函数返回所有可能的解决方案列表(一个解决方案是 <旋转向量,平移向量> 对),具体取决于输入点数和所选方法:

  • P3P 方法(SOLVEPNP_P3PSOLVEPNP_AP3P):3 或 4 个输入点。3 个输入点时返回的解决方案数可以在 0 到 4 之间。
  • SOLVEPNP_IPPE 输入点必须 >= 4 且对象点必须共面。返回 2 个解决方案。
  • SOLVEPNP_IPPE_SQUARE 适用于标记姿态估计的特殊情况。输入点数必须为 4,返回 2 个解决方案。对象点必须按以下顺序定义:
    • 点 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 且对象点可以是任何配置。只返回 1 个解决方案。
参数
objectPoints对象坐标空间中的对象点数组,Nx3 1 通道或 1xN/Nx1 3 通道,其中 N 是点数。这里也可以传递 vector<Point3d>。
imagePoints对应的图像点数组,Nx2 1 通道或 1xN/Nx1 2 通道,其中 N 是点数。这里也可以传递 vector<Point2d>。
cameraMatrix输入相机内参矩阵 \(\cameramatrix{A}\)。
distCoeffs输入畸变系数向量 \(\distcoeffs\)。如果向量为 NULL/空,则假定畸变系数为零。
rvecs输出旋转向量的向量(参见 Rodrigues),与 tvecs 一起将点从模型坐标系转换到相机坐标系。
tvecs输出平移向量的向量。
useExtrinsicGuess用于 SOLVEPNP_ITERATIVE 的参数。如果为 true (1),则函数使用提供的 rvec 和 tvec 值作为旋转和平移向量的初始近似值,并进一步优化它们。
flags (标志)解决 PnP 问题的方法:参见 calib3d_solvePnP_flags
rvec当 flags 为 SOLVEPNP_ITERATIVE 且 useExtrinsicGuess 设置为 true 时,用于初始化迭代 PnP 精炼算法的旋转向量。
tvec当 flags 为 SOLVEPNP_ITERATIVE 且 useExtrinsicGuess 设置为 true 时,用于初始化迭代 PnP 精炼算法的平移向量。
reprojectionError重投影误差的可选向量,即输入图像点与用估计姿态投影的 3D 对象点之间的 RMS 误差(\( \text{RMSE} = \sqrt{\frac{\sum_{i}^{N} \left ( \hat{y_i} - y_i \right )^2}{N}} \))。

更多信息请参见 Perspective-n-Point (PnP) 姿态计算

注意
  • 如何在平面增强现实中使用 solvePnP 的示例可以在 opencv_source_code/samples/python/plane_ar.py 中找到。
  • 如果您正在使用 Python
    • Numpy 数组切片不能作为输入,因为 solvePnP 需要连续数组(由 modules/calib3d/src/solvepnp.cpp 版本 2.4.9 第 55 行左右的 cv::Mat::checkVector() 断言强制执行)。
    • P3P 算法要求图像点为形状 (N,1,2) 的数组,因为它调用了 undistortPoints(modules/calib3d/src/solvepnp.cpp 版本 2.4.9 第 75 行左右),该函数需要 2 通道信息。
    • 因此,给定一些数据 D = np.array(...),其中 D.shape = (N,M),为了将其子集用作(例如)imagePoints,必须将其有效地复制到一个新数组中:imagePoints = np.ascontiguousarray(D[:,:2]).reshape((N,1,2))
  • 方法 SOLVEPNP_DLSSOLVEPNP_UPNP 不能使用,因为当前的实现不稳定,有时会给出完全错误的结果。如果您传递这两个标志中的一个,将改用 SOLVEPNP_EPNP 方法。
  • 在一般情况下,最小点数为 4。对于 SOLVEPNP_P3PSOLVEPNP_AP3P 方法,需要精确使用 4 个点(前 3 个点用于估计 P3P 问题的所有解,最后一个点用于保留最小化重投影误差的最佳解)。
  • 使用 SOLVEPNP_ITERATIVE 方法且 useExtrinsicGuess=true 时,最小点数为 3(3 个点足以计算姿态,但最多有 4 个解)。初始解应接近全局解才能收敛。
  • 使用 SOLVEPNP_IPPE 输入点必须 >= 4 且对象点必须共面。
  • 使用 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]
  • 使用 SOLVEPNP_SQPNP 输入点必须 >= 3

◆ solvePnPRansac() [1/2]

bool cv::solvePnPRansac ( InputArray objectPoints,
InputArray imagePoints,
InputArray cameraMatrix,
InputArray distCoeffs,
OutputArray rvec,
OutputArray tvec,
bool useExtrinsicGuess = false,
int iterationsCount = 100,
float reprojectionError = 8.0,
double confidence = 0.99,
OutputArray inliers = noArray(),
int flags = SOLVEPNP_ITERATIVE )
Python
cv.solvePnPRansac(objectPoints, imagePoints, cameraMatrix, distCoeffs[, rvec[, tvec[, useExtrinsicGuess[, iterationsCount[, reprojectionError[, confidence[, inliers[, flags]]]]]]]]) -> retval, rvec, tvec, inliers
cv.solvePnPRansac(objectPoints, imagePoints, cameraMatrix, distCoeffs[, rvec[, tvec[, inliers[, params]]]]) -> retval, cameraMatrix, rvec, tvec, inliers

#include <opencv2/calib3d.hpp>

利用 RANSAC 方案从 3D-2D 点对应关系中寻找物体姿态 \( {}^{c}\mathbf{T}_o \),以处理错误匹配。

透视投影,从对象帧到相机帧
另请参阅
透视-n-点 (PnP) 姿态计算
参数
objectPoints对象坐标空间中的对象点数组,Nx3 1 通道或 1xN/Nx1 3 通道,其中 N 是点数。这里也可以传递 vector<Point3d>。
imagePoints对应的图像点数组,Nx2 1 通道或 1xN/Nx1 2 通道,其中 N 是点数。这里也可以传递 vector<Point2d>。
cameraMatrix输入相机内参矩阵 \(\cameramatrix{A}\)。
distCoeffs输入畸变系数向量 \(\distcoeffs\)。如果向量为 NULL/空,则假定畸变系数为零。
rvec输出旋转向量(参见 Rodrigues),与 tvec 一起将点从模型坐标系转换到相机坐标系。
tvec输出平移向量。
useExtrinsicGuess用于 SOLVEPNP_ITERATIVE 的参数。如果为 true (1),则函数使用提供的 rvec 和 tvec 值作为旋转和平移向量的初始近似值,并进一步优化它们。
iterationsCount迭代次数。
reprojectionErrorRANSAC 过程使用的内点阈值。参数值是观测点和计算点投影之间的最大允许距离,以将其视为内点。
confidence算法产生有用结果的概率。
inliers输出向量,包含 objectPoints 和 imagePoints 中内点的索引。
flags (标志)解决 PnP 问题的方法(参见 solvePnP)。

该函数根据一组对象点、它们对应的图像投影以及相机内参矩阵和畸变系数来估计对象姿态。该函数找到最小化重投影误差的姿态,即观测投影 imagePoints 与投影(使用 projectPoints)对象点之间的平方距离之和。使用 RANSAC 使该函数对异常值具有鲁棒性。

注意

◆ solvePnPRansac() [2/2]

bool cv::solvePnPRansac ( InputArray objectPoints,
InputArray imagePoints,
InputOutputArray cameraMatrix,
InputArray distCoeffs,
OutputArray rvec,
OutputArray tvec,
OutputArray inliers,
const UsacParams & params = UsacParams() )
Python
cv.solvePnPRansac(objectPoints, imagePoints, cameraMatrix, distCoeffs[, rvec[, tvec[, useExtrinsicGuess[, iterationsCount[, reprojectionError[, confidence[, inliers[, flags]]]]]]]]) -> retval, rvec, tvec, inliers
cv.solvePnPRansac(objectPoints, imagePoints, cameraMatrix, distCoeffs[, rvec[, tvec[, inliers[, params]]]]) -> retval, cameraMatrix, rvec, tvec, inliers

#include <opencv2/calib3d.hpp>

◆ solvePnPRefineLM()

void cv::solvePnPRefineLM ( InputArray objectPoints,
InputArray imagePoints,
InputArray cameraMatrix,
InputArray distCoeffs,
InputOutputArray rvec,
InputOutputArray tvec,
TermCriteria criteria = TermCriteria(TermCriteria::EPS+TermCriteria::COUNT, 20, FLT_EPSILON) )
Python
cv.solvePnPRefineLM(objectPoints, imagePoints, cameraMatrix, distCoeffs, rvec, tvec[, criteria]) -> rvec, tvec

#include <opencv2/calib3d.hpp>

基于 3D-2D 点对应关系,从初始解开始精细化姿态(将物体坐标系中的 3D 点变换到相机坐标系的平移和旋转向量)。

另请参阅
透视-n-点 (PnP) 姿态计算
参数
objectPoints对象坐标空间中的对象点数组,Nx3 1 通道或 1xN/Nx1 3 通道,其中 N 是点数。这里也可以传递 vector<Point3d>。
imagePoints对应的图像点数组,Nx2 1 通道或 1xN/Nx1 2 通道,其中 N 是点数。这里也可以传递 vector<Point2d>。
cameraMatrix输入相机内参矩阵 \(\cameramatrix{A}\)。
distCoeffs输入畸变系数向量 \(\distcoeffs\)。如果向量为 NULL/空,则假定畸变系数为零。
rvec输入/输出旋转向量(参见 Rodrigues),与 tvec 一起将点从模型坐标系转换到相机坐标系。输入值用作初始解。
tvec输入/输出平移向量。输入值用作初始解。
criteriaLevenberg-Marquard 迭代算法停止的条件。

该函数细化对象姿态,给定至少 3 个对象点、它们对应的图像投影、旋转和平移向量的初始解以及相机内参矩阵和畸变系数。该函数根据 Levenberg-Marquardt 迭代最小化 [184] [81] 过程,最小化相对于旋转和平移向量的投影误差。

◆ solvePnPRefineVVS()

void cv::solvePnPRefineVVS ( InputArray objectPoints,
InputArray imagePoints,
InputArray cameraMatrix,
InputArray distCoeffs,
InputOutputArray rvec,
InputOutputArray tvec,
TermCriteria criteria = TermCriteria(TermCriteria::EPS+TermCriteria::COUNT, 20, FLT_EPSILON),
double VVSlambda = 1 )
Python
cv.solvePnPRefineVVS(objectPoints, imagePoints, cameraMatrix, distCoeffs, rvec, tvec[, criteria[, VVSlambda]]) -> rvec, tvec

#include <opencv2/calib3d.hpp>

基于 3D-2D 点对应关系,从初始解开始精细化姿态(将物体坐标系中的 3D 点变换到相机坐标系的平移和旋转向量)。

另请参阅
透视-n-点 (PnP) 姿态计算
参数
objectPoints对象坐标空间中的对象点数组,Nx3 1 通道或 1xN/Nx1 3 通道,其中 N 是点数。这里也可以传递 vector<Point3d>。
imagePoints对应的图像点数组,Nx2 1 通道或 1xN/Nx1 2 通道,其中 N 是点数。这里也可以传递 vector<Point2d>。
cameraMatrix输入相机内参矩阵 \(\cameramatrix{A}\)。
distCoeffs输入畸变系数向量 \(\distcoeffs\)。如果向量为 NULL/空,则假定畸变系数为零。
rvec输入/输出旋转向量(参见 Rodrigues),与 tvec 一起将点从模型坐标系转换到相机坐标系。输入值用作初始解。
tvec输入/输出平移向量。输入值用作初始解。
criteriaLevenberg-Marquard 迭代算法停止的条件。
VVSlambda虚拟视觉伺服控制律的增益,等同于阻尼高斯-牛顿公式中的 \(\alpha\) 增益。

该函数细化对象姿态,给定至少 3 个对象点、它们对应的图像投影、旋转和平移向量的初始解以及相机内参矩阵和畸变系数。该函数使用虚拟视觉伺服 (VVS) [54] [188] 方案,最小化相对于旋转和平移向量的投影误差。

◆ stereoCalibrate() [1/3]

double cv::stereoCalibrate ( InputArrayOfArrays objectPoints,
InputArrayOfArrays imagePoints1,
InputArrayOfArrays imagePoints2,
InputOutputArray cameraMatrix1,
InputOutputArray distCoeffs1,
InputOutputArray cameraMatrix2,
InputOutputArray distCoeffs2,
Size imageSize,
InputOutputArray R,
InputOutputArray T,
OutputArray E,
OutputArray F,
OutputArray perViewErrors,
int flags = CALIB_FIX_INTRINSIC,
TermCriteria criteria = TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, 1e-6) )
Python
cv.stereoCalibrate(objectPoints, imagePoints1, imagePoints2, cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2, imageSize[, R[, T[, E[, F[, flags[, criteria]]]]]]) -> retval, cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2, R, T, E, F
cv.stereoCalibrate(objectPoints, imagePoints1, imagePoints2, cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2, imageSize, R, T[, E[, F[, perViewErrors[, flags[, criteria]]]]]) -> retval, cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2, R, T, E, F, perViewErrors
cv.stereoCalibrateExtended(objectPoints, imagePoints1, imagePoints2, cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2, imageSize, R, T[, E[, F[, rvecs[, tvecs[, perViewErrors[, flags[, criteria]]]]]]]) -> retval, cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2, R, T, E, F, rvecs, tvecs, perViewErrors

#include <opencv2/calib3d.hpp>

这是一个重载的成员函数,为方便起见而提供。它与上述函数的区别仅在于所接受的参数不同。

◆ stereoCalibrate() [2/3]

double cv::stereoCalibrate ( InputArrayOfArrays objectPoints,
InputArrayOfArrays imagePoints1,
InputArrayOfArrays imagePoints2,
InputOutputArray cameraMatrix1,
InputOutputArray distCoeffs1,
InputOutputArray cameraMatrix2,
InputOutputArray distCoeffs2,
Size imageSize,
InputOutputArray R,
InputOutputArray T,
OutputArray E,
OutputArray F,
OutputArrayOfArrays rvecs,
OutputArrayOfArrays tvecs,
OutputArray perViewErrors,
int flags = CALIB_FIX_INTRINSIC,
TermCriteria criteria = TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, 1e-6) )
Python
cv.stereoCalibrate(objectPoints, imagePoints1, imagePoints2, cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2, imageSize[, R[, T[, E[, F[, flags[, criteria]]]]]]) -> retval, cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2, R, T, E, F
cv.stereoCalibrate(objectPoints, imagePoints1, imagePoints2, cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2, imageSize, R, T[, E[, F[, perViewErrors[, flags[, criteria]]]]]) -> retval, cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2, R, T, E, F, perViewErrors
cv.stereoCalibrateExtended(objectPoints, imagePoints1, imagePoints2, cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2, imageSize, R, T[, E[, F[, rvecs[, tvecs[, perViewErrors[, flags[, criteria]]]]]]]) -> retval, cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2, R, T, E, F, rvecs, tvecs, perViewErrors

#include <opencv2/calib3d.hpp>

标定双目相机设置。此函数计算两个相机各自的内参数,以及两个相机之间的外参数。

参数
objectPoints校准模式点的向量的向量。与 calibrateCamera 中的结构相同。对于每个模式视图,两个相机都需要看到相同的对象点。因此,objectPoints.size()、imagePoints1.size() 和 imagePoints2.size() 需要相等,并且对于每个 i,objectPoints[i].size()、imagePoints1[i].size() 和 imagePoints2[i].size() 也需要相等。
imagePoints1由第一个相机观测到的校准模式点投影的向量的向量。与 calibrateCamera 中的结构相同。
imagePoints2由第二个相机观测到的校准模式点投影的向量的向量。与 calibrateCamera 中的结构相同。
cameraMatrix1第一个相机的输入/输出相机内参矩阵,与 calibrateCamera 中相同。此外,对于立体情况,可以使用额外的标志,请参阅下文。
distCoeffs1输入/输出畸变系数向量,与 calibrateCamera 中相同。
cameraMatrix2第二个相机的输入/输出相机内参矩阵。参见 cameraMatrix1 的描述。
distCoeffs2第二个相机的输入/输出镜头畸变系数。参见 distCoeffs1 的描述。
imageSize仅用于初始化相机内参矩阵的图像大小。
R输出旋转矩阵。与平移向量 T 一起,此矩阵将第一个相机坐标系中的点转换到第二个相机坐标系中的点。更专业地说,R 和 T 的元组执行从第一个相机坐标系到第二个相机坐标系的基变换。由于其对偶性,此元组等同于第一个相机相对于第二个相机坐标系的位置。
T输出平移向量,参见上面描述。
E输出本质矩阵。
F输出基础矩阵。
rvecs针对立体对的第一个相机的坐标系中估计的每个模式视图的旋转向量(Rodrigues)向量(例如 std::vector<cv::Mat>)。更详细地说,每个第 i 个旋转向量与相应的第 i 个平移向量(参见下一个输出参数描述)一起,将校准模式从对象坐标空间(其中指定了对象点)转换到立体对的第一个相机的相机坐标空间。更专业地说,第 i 个旋转和平移向量的元组执行从对象坐标空间到立体对的第一个相机的相机坐标空间的基变换。
tvecs估计的每个模式视图的平移向量的向量,参见上一个输出参数 (rvecs) 的参数描述。
perViewErrors为每个模式视图估计的RMS重投影误差输出向量。
flags (标志)可以是零或以下值的组合的不同标志
  • CALIB_SAME_FOCAL_LENGTH 强制 \(f^{(0)}_x=f^{(1)}_x\) 和 \(f^{(0)}_y=f^{(1)}_y\)。
  • CALIB_ZERO_TANGENT_DIST 将每个相机的切向畸变系数设置为零并固定。
  • CALIB_FIX_K1,..., CALIB_FIX_K6 在优化期间不改变相应的径向畸变系数。如果设置了 CALIB_USE_INTRINSIC_GUESS,则使用提供的 distCoeffs 矩阵中的系数。否则,将其设置为 0。
  • CALIB_RATIONAL_MODEL 启用系数 k4、k5 和 k6。为了提供向后兼容性,应明确指定此额外标志,使校准函数使用有理模型并返回 8 个系数。如果未设置此标志,函数将只计算并返回 5 个畸变系数。
  • CALIB_THIN_PRISM_MODEL 启用系数 s1、s2、s3 和 s4。为了提供向后兼容性,应明确指定此额外标志,使校准函数使用薄棱镜模型并返回 12 个系数。如果未设置此标志,函数将只计算并返回 5 个畸变系数。
  • CALIB_FIX_S1_S2_S3_S4 在优化期间不改变薄棱镜畸变系数。如果设置了 CALIB_USE_INTRINSIC_GUESS,则使用提供的 distCoeffs 矩阵中的系数。否则,将其设置为 0。
  • CALIB_TILTED_MODEL 启用系数 tauX 和 tauY。为了提供向后兼容性,应明确指定此额外标志,使校准函数使用倾斜传感器模型并返回 14 个系数。如果未设置此标志,函数将只计算并返回 5 个畸变系数。
  • CALIB_FIX_TAUX_TAUY 在优化期间不改变倾斜传感器模型的系数。如果设置了 CALIB_USE_INTRINSIC_GUESS,则使用提供的 distCoeffs 矩阵中的系数。否则,将其设置为 0。
criteria迭代优化算法的终止条件。

该函数估计构成立体对的两个相机之间的变换。如果计算一个物体相对于第一个相机和第二个相机的姿态,分别为(\(R_1\), \(T_1\))和(\(R_2\), \(T_2\)),对于两个相机之间相对位置和方向固定的立体相机,这些姿态之间肯定存在关联。这意味着,如果已知两个相机的相对位置和方向(\(R\), \(T\)),则在给定(\(R_1\), \(T_1\))时可以计算(\(R_2\), \(T_2\))。这就是所描述函数的作用。它计算(\(R\), \(T\)),使得

\[R_2=R R_1\]

\[T_2=R T_1 + T.\]

因此,当给定一个3D点在第一个相机坐标系中的坐标表示时,可以计算出该点在第二个相机坐标系中的坐标表示

\[\begin{bmatrix} X_2 \\ Y_2 \\ Z_2 \\ 1 \end{bmatrix} = \begin{bmatrix} R & T \\ 0 & 1 \end{bmatrix} \begin{bmatrix} X_1 \\ Y_1 \\ Z_1 \\ 1 \end{bmatrix}.\]

可选地,它计算本征矩阵 E

\[E= \vecthreethree{0}{-T_2}{T_1}{T_2}{0}{-T_0}{-T_1}{T_0}{0} R\]

其中 \(T_i\) 是平移向量 \(T\) 的分量: \(T=[T_0, T_1, T_2]^T\) 。该函数还可以计算基本矩阵 F

\[F = cameraMatrix2^{-T}\cdot E \cdot cameraMatrix1^{-1}\]

除了立体相关信息外,该函数还可以对两个相机中的每一个进行完整校准。然而,由于参数空间的高维度和输入数据中的噪声,该函数可能会偏离正确解。如果可以单独高精度地估计每个相机的内参(例如,使用 calibrateCamera ),建议您这样做,然后将 CALIB_FIX_INTRINSIC 标志以及计算出的内参传递给该函数。否则,如果所有参数都一次性估计,则限制某些参数是有意义的,例如,传递 CALIB_SAME_FOCAL_LENGTHCALIB_ZERO_TANGENT_DIST 标志,这通常是一个合理的假设。

calibrateCamera 类似,该函数最小化所有可用视图中来自两个相机的所有点的总重投影误差。该函数返回重投影误差的最终值。

◆ stereoCalibrate() [3/3]

double cv::stereoCalibrate ( InputArrayOfArrays objectPoints,
InputArrayOfArrays imagePoints1,
InputArrayOfArrays imagePoints2,
InputOutputArray cameraMatrix1,
InputOutputArray distCoeffs1,
InputOutputArray cameraMatrix2,
InputOutputArray distCoeffs2,
Size imageSize,
OutputArray R,
OutputArray T,
OutputArray E,
OutputArray F,
int flags = CALIB_FIX_INTRINSIC,
TermCriteria criteria = TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, 1e-6) )
Python
cv.stereoCalibrate(objectPoints, imagePoints1, imagePoints2, cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2, imageSize[, R[, T[, E[, F[, flags[, criteria]]]]]]) -> retval, cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2, R, T, E, F
cv.stereoCalibrate(objectPoints, imagePoints1, imagePoints2, cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2, imageSize, R, T[, E[, F[, perViewErrors[, flags[, criteria]]]]]) -> retval, cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2, R, T, E, F, perViewErrors
cv.stereoCalibrateExtended(objectPoints, imagePoints1, imagePoints2, cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2, imageSize, R, T[, E[, F[, rvecs[, tvecs[, perViewErrors[, flags[, criteria]]]]]]]) -> retval, cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2, R, T, E, F, rvecs, tvecs, perViewErrors

#include <opencv2/calib3d.hpp>

这是一个重载的成员函数,为方便起见而提供。它与上述函数的区别仅在于所接受的参数不同。

◆ stereoRectify()

void cv::stereoRectify ( InputArray cameraMatrix1,
InputArray distCoeffs1,
InputArray cameraMatrix2,
InputArray distCoeffs2,
Size imageSize,
InputArray R,
InputArray T,
OutputArray R1,
OutputArray R2,
OutputArray P1,
OutputArray P2,
OutputArray Q,
int flags = CALIB_ZERO_DISPARITY,
double alpha = -1,
Size newImageSize = Size(),
Rect * validPixROI1 = 0,
Rect * validPixROI2 = 0 )
Python
cv.stereoRectify(cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2, imageSize, R, T[, R1[, R2[, P1[, P2[, Q[, flags[, alpha[, newImageSize]]]]]]]]) -> R1, R2, P1, P2, Q, validPixROI1, validPixROI2

#include <opencv2/calib3d.hpp>

为已标定的立体相机的每个镜头计算校正变换。

参数
cameraMatrix1第一个相机内参矩阵。
distCoeffs1第一个相机畸变参数。
cameraMatrix2第二个相机内参矩阵。
distCoeffs2第二个相机畸变参数。
imageSize用于立体校准的图像大小。
R从第一个相机坐标系到第二个相机坐标系的旋转矩阵,参见 stereoCalibrate
T从第一个相机坐标系到第二个相机坐标系的平移向量,参见 stereoCalibrate
R1第一个相机的输出 3x3 整流变换(旋转矩阵)。此矩阵将未整流的第一个相机坐标系中的点转换为整流的第一个相机坐标系中的点。更专业地说,它执行从未整流的第一个相机坐标系到整流的第一个相机坐标系的基变换。
R2第二个相机的输出 3x3 整流变换(旋转矩阵)。此矩阵将未整流的第二个相机坐标系中的点转换为整流的第二个相机坐标系中的点。更专业地说,它执行从未整流的第二个相机坐标系到整流的第二个相机坐标系的基变换。
P1第一个相机在新(整流)坐标系中的输出 3x4 投影矩阵,即它将整流的第一个相机坐标系中的点投影到整流的第一个相机图像中。
P2第二个相机在新(整流)坐标系中的输出 3x4 投影矩阵,即它将整流的第一个相机坐标系中的点投影到整流的第二个相机图像中。
Q输出 \(4 \times 4\) 视差到深度映射矩阵(参见 reprojectImageTo3D)。
flags (标志)操作标志,可以是零或 CALIB_ZERO_DISPARITY 。如果设置了该标志,函数将使每个相机的主点在整流视图中具有相同的像素坐标。如果未设置该标志,函数仍可能在水平或垂直方向(取决于外极线的方向)移动图像以最大化有效图像区域。
alpha自由缩放参数。如果为 -1 或缺失,函数执行默认缩放。否则,参数应在 0 到 1 之间。alpha=0 表示整流图像被缩放和平移,以便只有有效像素可见(整流后没有黑色区域)。alpha=1 表示整流图像被抽样和平移,以便原始图像中来自相机的所有像素都保留在整流图像中(没有源图像像素丢失)。任何中间值都会产生介于这两个极端情况之间的中间结果。
新图像分辨率整流后的新图像分辨率。应将相同的大小传递给 initUndistortRectifyMap (参见 OpenCV 示例目录中的 stereo_calib.cpp 示例)。当传递 (0,0) (默认)时,它被设置为原始 imageSize。将其设置为更大的值可以帮助您保留原始图像中的细节,尤其是在存在较大径向畸变时。
有效像素ROI1整流图像中所有像素都有效的可选输出矩形。如果 alpha=0,ROI 覆盖整个图像。否则,它们可能更小(参见下图)。
有效像素ROI2整流图像中所有像素都有效的可选输出矩形。如果 alpha=0,ROI 覆盖整个图像。否则,它们可能更小(参见下图)。

该函数计算每个相机的旋转矩阵,这些矩阵(虚拟地)使两个相机的图像平面处于同一平面。因此,这使得所有对极线平行,从而简化了稠密立体对应问题。该函数以 stereoCalibrate 计算的矩阵作为输入。作为输出,它提供两个旋转矩阵以及新坐标中的两个投影矩阵。该函数区分以下两种情况

  • 水平立体:第一个和第二个相机视图主要沿 x 轴相互偏移(可能存在小的垂直偏移)。在整流图像中,左右相机中对应的对极线是水平的,并且具有相同的 y 坐标。P1 和 P2 看起来像

    \[\texttt{P1} = \begin{bmatrix} f & 0 & cx_1 & 0 \\ 0 & f & cy & 0 \\ 0 & 0 & 1 & 0 \end{bmatrix}\]

    \[\texttt{P2} = \begin{bmatrix} f & 0 & cx_2 & T_x \cdot f \\ 0 & f & cy & 0 \\ 0 & 0 & 1 & 0 \end{bmatrix} ,\]

    \[\texttt{Q} = \begin{bmatrix} 1 & 0 & 0 & -cx_1 \\ 0 & 1 & 0 & -cy \\ 0 & 0 & 0 & f \\ 0 & 0 & -\frac{1}{T_x} & \frac{cx_1 - cx_2}{T_x} \end{bmatrix} \]

    其中 \(T_x\) 是相机之间的水平偏移,如果设置了 CALIB_ZERO_DISPARITY ,则 \(cx_1=cx_2\)。

  • 垂直立体:第一个和第二个相机视图主要在垂直方向上相互偏移(并且可能在水平方向上也有一点偏移)。整流图像中的对极线是垂直的,并且具有相同的 x 坐标。P1 和 P2 看起来像

    \[\texttt{P1} = \begin{bmatrix} f & 0 & cx & 0 \\ 0 & f & cy_1 & 0 \\ 0 & 0 & 1 & 0 \end{bmatrix}\]

    \[\texttt{P2} = \begin{bmatrix} f & 0 & cx & 0 \\ 0 & f & cy_2 & T_y \cdot f \\ 0 & 0 & 1 & 0 \end{bmatrix},\]

    \[\texttt{Q} = \begin{bmatrix} 1 & 0 & 0 & -cx \\ 0 & 1 & 0 & -cy_1 \\ 0 & 0 & 0 & f \\ 0 & 0 & -\frac{1}{T_y} & \frac{cy_1 - cy_2}{T_y} \end{bmatrix} \]

    其中 \(T_y\) 是相机之间的垂直偏移,如果设置了 CALIB_ZERO_DISPARITY ,则 \(cy_1=cy_2\)。

如您所见,P1 和 P2 的前三列将有效地成为新的“整流”相机矩阵。然后,这些矩阵以及 R1 和 R2 可以传递给 initUndistortRectifyMap 以初始化每个相机的整流图。

参见下面的 stereo_calib.cpp 示例截图。一些红色水平线穿过相应的图像区域。这意味着图像已很好地整流,这是大多数立体对应算法所依赖的。绿色矩形是 roi1 和 roi2。您可以看到它们的内部都是有效像素。

图像

◆ stereoRectifyUncalibrated()

bool cv::stereoRectifyUncalibrated ( InputArray points1,
InputArray points2,
InputArray F,
Size 图像尺寸,
OutputArray H1,
OutputArray H2,
double threshold = 5 )
Python
cv.stereoRectifyUncalibrated(points1, points2, F, imgSize[, H1[, H2[, threshold]]]) -> 返回值, H1, H2

#include <opencv2/calib3d.hpp>

为未标定的立体相机计算校正变换。

参数
points1第一个图像中的特征点数组。
points2第二个图像中对应的点。支持与 findFundamentalMat 相同的格式。
F输入基本矩阵。可以使用 findFundamentalMat 从同一组点对计算。
图像尺寸图像大小。
H1第一个图像的输出整流单应矩阵。
H2第二个图像的输出整流单应矩阵。
阈值 (threshold)用于滤除异常值的可选阈值。如果参数大于零,则所有不符合对极几何的点对(即,对于 \(|\texttt{points2[i]}^T \cdot \texttt{F} \cdot \texttt{points1[i]}|>\texttt{threshold}\) 的点)在计算单应矩阵之前被拒绝。否则,所有点都被视为内点。

该函数在不知道相机内参及其在空间中的相对位置的情况下计算整流变换,这就是“未校准”后缀的原因。与 stereoRectify 的另一个相关区别是,该函数输出的不是对象(3D)空间中的整流变换,而是由单应矩阵 H1 和 H2 编码的平面透视变换。该函数实现了算法 [121]

注意
虽然该算法不需要知道相机的内参,但它严重依赖于对极几何。因此,如果相机镜头有显著畸变,最好在计算基本矩阵和调用此函数之前对其进行校正。例如,可以使用 calibrateCamera 分别估计立体相机每个头部的畸变系数。然后,可以使用 undistort 校正图像,或者只使用 undistortPoints 校正点坐标。

◆ triangulatePoints()

void cv::triangulatePoints ( InputArray 投影矩阵1,
InputArray 投影矩阵2,
InputArray 投影点1,
InputArray 投影点2,
OutputArray 点4D )
Python
cv.triangulatePoints(projMatr1, projMatr2, projPoints1, projPoints2[, points4D]) -> 点4D

#include <opencv2/calib3d.hpp>

此函数利用立体相机的观测结果重建三维点(齐次坐标)。

参数
投影矩阵1第一个相机的 3x4 投影矩阵,即此矩阵将世界坐标系中给定的 3D 点投影到第一个图像中。
投影矩阵2第二个相机的 3x4 投影矩阵,即此矩阵将世界坐标系中给定的 3D 点投影到第二个图像中。
投影点1第一个图像中的 2xN 数组特征点。在 c++ 版本中,它也可以是特征点向量或 1xN 或 Nx1 大小的双通道矩阵。
投影点2第二个图像中对应的 2xN 数组点。在 c++ 版本中,它也可以是特征点向量或 1xN 或 Nx1 大小的双通道矩阵。
点4D齐次坐标中重建点的 4xN 数组。这些点在世界坐标系中返回。
注意
请记住,所有输入数据都应为浮点类型,以便此函数工作。
如果使用 stereoRectify 的投影矩阵,则返回的点表示在第一个相机的整流坐标系中。
另请参阅
reprojectImageTo3D

◆ undistort()

void cv::undistort ( InputArray src,
OutputArray dst,
InputArray cameraMatrix,
InputArray distCoeffs,
InputArray newCameraMatrix = noArray() )
Python
cv.undistort(src, cameraMatrix, distCoeffs[, dst[, newCameraMatrix]]) -> dst

#include <opencv2/calib3d.hpp>

对图像进行变换以补偿镜头畸变。

该函数对图像进行变换以补偿径向和切向镜头畸变。

该函数只是 initUndistortRectifyMap (使用单位 R)和 remap (使用双线性插值)的组合。有关所执行变换的详细信息,请参见前一个函数。

目标图像中没有对应像素的像素将填充零(黑色)。

校正图像中可见的源图像的特定子集可以通过 newCameraMatrix 进行调节。您可以使用 getOptimalNewCameraMatrix 根据您的要求计算合适的 newCameraMatrix。

相机矩阵和畸变参数可以使用 calibrateCamera 确定。如果图像分辨率与校准阶段使用的分辨率不同,则需要相应地缩放 \(f_x, f_y, c_x\) 和 \(c_y\),而畸变系数保持不变。

参数
src输入(畸变)图像。
dst输出(校正)图像,其大小和类型与 src 相同。
cameraMatrix输入相机矩阵 \(A = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\) 。
distCoeffs畸变系数向量 \((k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6[, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]])\),包含 4、5、8、12 或 14 个元素。如果向量为 NULL/空,则假定畸变系数为零。
newCameraMatrix畸变图像的相机矩阵。默认情况下,它与 cameraMatrix 相同,但您可以通过使用不同的矩阵来额外缩放和移动结果。

◆ undistortImagePoints()

void cv::undistortImagePoints ( InputArray src,
OutputArray dst,
InputArray cameraMatrix,
InputArray distCoeffs,
TermCriteria = TermCriteria(TermCriteria::MAX_ITER, 5, 0.01) )
Python
cv.undistortImagePoints(src, cameraMatrix, distCoeffs[, dst[, arg1]]) -> dst

#include <opencv2/calib3d.hpp>

计算去畸变后的图像点位置。

参数
src观测点位置,2xN/Nx2 1通道或1xN/Nx1 2通道(CV_32FC2或CV_64FC2)(或 vector<Point2f>)。
dst输出去畸变点位置(1xN/Nx1 2通道或 vector<Point2f>)。
cameraMatrix相机矩阵 \(\vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\) 。
distCoeffs畸变系数

◆ undistortPoints() [1/2]

void cv::undistortPoints ( InputArray src,
OutputArray dst,
InputArray cameraMatrix,
InputArray distCoeffs,
InputArray R,
InputArray P,
TermCriteria criteria )
Python
cv.undistortPoints(src, cameraMatrix, distCoeffs[, dst[, R[, P]]]) -> dst
cv.undistortPointsIter(src, cameraMatrix, distCoeffs, R, P, criteria[, dst]) -> dst

#include <opencv2/calib3d.hpp>

这是一个重载的成员函数,为方便起见而提供。它与上述函数的区别仅在于所接受的参数不同。

注意
undistortPoints 的默认版本执行 5 次迭代以计算去畸变点。

◆ undistortPoints() [2/2]

void cv::undistortPoints ( InputArray src,
OutputArray dst,
InputArray cameraMatrix,
InputArray distCoeffs,
InputArray R = noArray(),
InputArray P = noArray() )
Python
cv.undistortPoints(src, cameraMatrix, distCoeffs[, dst[, R[, P]]]) -> dst
cv.undistortPointsIter(src, cameraMatrix, distCoeffs, R, P, criteria[, dst]) -> dst

#include <opencv2/calib3d.hpp>

根据观测到的点坐标计算理想点坐标。

此函数类似于 undistortinitUndistortRectifyMap,但它作用于稀疏点集而不是栅格图像。此外,该函数执行 projectPoints 的反向变换。对于 3D 对象,它不重建其 3D 坐标,但对于平面对象,如果在指定了适当的 R 的情况下,它会重建,直到平移向量。

对于每个观察到的点坐标 \((u, v)\),函数计算

\[ \begin{array}{l} x^{"} \leftarrow (u - c_x)/f_x \\ y^{"} \leftarrow (v - c_y)/f_y \\ (x',y') = undistort(x^{"},y^{"}, \texttt{distCoeffs}) \\ {[X\,Y\,W]} ^T \leftarrow R*[x' \, y' \, 1]^T \\ x \leftarrow X/W \\ y \leftarrow Y/W \\ \text{仅当P被指定时执行:} \\ u' \leftarrow x {f'}_x + {c'}_x \\ v' \leftarrow y {f'}_y + {c'}_y \end{array} \]

其中 undistort 是一种近似迭代算法,它根据归一化的畸变点坐标估计归一化的原始点坐标(“归一化”意味着坐标不依赖于相机矩阵)。

该函数可用于立体相机头或单目相机(当 R 为空时)。

参数
src观测点坐标,2xN/Nx2 1通道或1xN/Nx1 2通道(CV_32FC2或CV_64FC2)(或 vector<Point2f>)。
dst去畸变和反向透视变换后的输出理想点坐标(1xN/Nx1 2通道或 vector<Point2f>)。如果矩阵 P 为单位矩阵或省略,dst 将包含归一化点坐标。
cameraMatrix相机矩阵 \(\vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\) 。
distCoeffs畸变系数向量 \((k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6[, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]])\),包含 4、5、8、12 或 14 个元素。如果向量为 NULL/空,则假定畸变系数为零。
R对象空间中的整流变换(3x3 矩阵)。stereoRectify 计算的 R1 或 R2 可以在此处传递。如果矩阵为空,则使用单位变换。
P新的相机矩阵(3x3)或新的投影矩阵(3x4) \(\begin{bmatrix} {f'}_x & 0 & {c'}_x & t_x \\ 0 & {f'}_y & {c'}_y & t_y \\ 0 & 0 & 1 & t_z \end{bmatrix}\)。stereoRectify 计算的 P1 或 P2 可以在此处传递。如果矩阵为空,则使用单位新的相机矩阵。

◆ validateDisparity()

void cv::validateDisparity ( InputOutputArray disparity,
InputArray 成本,
int minDisparity,
int numberOfDisparities,
int disp12MaxDisp = 1 )
Python
cv.validateDisparity(disparity, cost, minDisparity, numberOfDisparities[, disp12MaxDisp]) -> disparity

#include <opencv2/calib3d.hpp>

使用左右检查(left-right check)验证视差。矩阵“cost”应由双目匹配算法计算得出。