上一个教程:交互式相机校准应用程序
| |
原作者 | 马西姆·伊瓦谢奇金 |
兼容性 | OpenCV >= 4.0 |
此作品已作为 Google Summer of Code 的一部分(2020 年 8 月)进行整合。
贡献
集成到 OpenCV calib3d
模块的部分是基于 RANSAC 的通用框架 USAC(namespace usac
),用 C++ 编写。该框架包括用于采样、验证或局部优化的不同先进方法。该框架的主要优势在于它独立于任何估计问题和模块化结构。因此,可以轻松添加/删除新的解算器或方法。到目前为止,它包括以下组件
- 采样方法
- 统一型——[90] 中提出的标准 RANSAC 采样,它独立均匀地随机绘制最小子集。这是提议框架中的默认选项。
- PROSAC——方法 [57] 假设输入数据点按质量排序,因此采样可以从最有希望的点开始。这种方法的对应关系可以通过以下方式排序:例如,通过从 SIFT 检测器获得的最佳匹配到次佳匹配的描述符距离比率。推荐使用此方法,因为它可以找到一个不错的模型并更早终止。
- NAPSAC——采样方法 [201] 在初始点随机地均匀选取并为最小样本的其余点选取初始点附近的点。如果模型已局部化,则此方法可能很有用。例如,用于平面拟合。然而,在实践中,很难解决退化问题和定义最佳邻域大小的问题。
- Progressive-NAPSAC——采样器 [17] 与 NAPSAC 类似,尽管它从局部开始逐渐收敛到全局采样。如果模型是局部的话,但是数据的分布可能是任意的,则此方法非常有用。已实现版本假定数据点按质量排序,就像在 PROSAC 中一样。
- 评分方法。USAC 及标准 RANSAC 会找到最小化总损失的模型。损失可以用以下函数表示
- RANSAC——二进制 0/1 损失。1 表示异常值,0 表示内点。如果目标是要找到尽可能多的内点,则这是一个不错的选择。
- MSAC——点到模型的截断平方误差距离。框架中的默认选项。模型可能没有使用 RANSAC 得分的那么多内点,但会更准确。
- MAGSAC – 无阈值方法 [18] 计算得分。因此使用最大 sigma(噪声的标准差)级别对 sigma 处的点残差进行边缘化。点的得分表示该点是内点的可能性。当图像噪声未知时推荐使用该选项,因为此方法不需要阈值。然而,仍建议至少提供一个近似的阈值,因为终止本身取决于误差小于阈值的点数。通过指定 0 阈值,在达到最大迭代次数后该方法将输出模型。
- LMeds – 最小平方误差距离的中值。在该框架中,使用 $O(n)$ 复杂度的快速排序算法可以有效地实现中值查找。请注意,在内点比例低于 50% 时,LMeds 不能正常工作,在其他情况下,该方法是稳健的并且不需要阈值。
- 描述点到估计模型的误差距离的误差度量。
- 重新投影距离 – 用于仿射、单应性和投影矩阵。对于单应性矩阵,还可以使用对称重新投影距离。
- Sampson 距离 – 用于基本矩阵。
- 对称几何距离 – 用于本质矩阵。
- 退化
- DEGENSAC – 方法 [60],用于基本矩阵估计,可有效验证和恢复模型,该模型在位于主平面上的最小样本中至少包含 5 个点。
- 共线性检验 – 对于仿射和单应性矩阵估计,检验是否存在 3 个点处在线上。对于单应性矩阵,由于这些点是平面的,因此应用了检验,检查最小样本中的点是否相对于样本中的任意两点相交的任何直线在同一侧(不假设计反射)。
- 面向极线限制 – 方法 [59] 用于极线几何,通过验证模型(基本和本质矩阵)来使点在相机的前面可见。
- SPRT 验证 – 方法 [184] 根据内点的概率、估算的相对时间、输出模型的平均数量等概率给定的统计属性,通过在随机乱序点上进行评估来验证模型。显著加快了框架,因为可以在不显式计算每个点的错误的情况下,非常快速地拒绝不良模型。
- 局部优化
- 局部优化的 RANSAC – 方法 [58],通过非最小估计,对迄今为止最好的模型进行迭代优化。框架中的默认选项。此过程最快,并且不逊于其他局部优化方法。
- 图分割 RANSAC – 方法 [16] 优化了迄今为止最好的模型,但是它利用数据点的空间一致性。此过程非常精确,但是计算速度较慢。
- 标准偏差协商 - 此方法[18]改善了模型,方法是应用非最小加权估计,其中权重使用与 MAGSAC 评分中相同的逻辑来计算。最好将此方法与 MAGSAC 评分一起使用。
- 终止
- 标准 - 适用于独立和均匀抽样的标准方程。
- PROSAC - PROSAC 的终止。
- SPRT - SPRT 的终止。
- 求解器。在此框架中,有最小和非最小求解器。在最小求解器中,应用了用于估计的标准方法。在非最小求解器中,通常会构建协方差矩阵并将模型作为对应于最高特征值的特征向量来查找。
- Affine2D 矩阵
- 单应性矩阵 - 对于最小求解器,使用 OpenCV 的 RHO(高斯消去)算法。
- 基础矩阵 - 对于 7 点算法,使用高斯消去(消去到上三角矩阵和向后代入)来查找两个零向量,而不是使用 SVD,然后求解 3 次多项式。对于 8 点求解器,也使用高斯消去。
- 本质矩阵 - 使用高斯消去找到 4 个零向量。然后使用[250]中所述的基于格罗布纳基的求解器。本质矩阵仅当安装了 LAPACK 或 Eigen 时才能计算,因为它需要使用具有复特征值的特征分解。
- 透视-n-点 - 最小求解器是经典的 3 点求解器,最多有 4 个解。对于 RANSAC,样本数量少起着重要作用,因为它需要的迭代次数更少,此外,平均而言,P3P 求解器有大约 1.39 个估计模型。此外,在具有
UsacParams
的 solvePnPRansac(...)
的新版本中,有一个选项可以传递空的内在矩阵 InputOutputArray cameraMatrix
。如果矩阵为空,则使用直接线性变换算法(6 点的 PnP),框架输出的不仅有旋转和平移向量,还有校准矩阵。
此外,该框架还可以并行运行。并行化方法是创建多个 RANSAC,它们共享两个原子变量 bool success
和 int num_hypothesis_tested
,这两个变量确定所有 RANSAC 何时必须终止。如果某个 RANSAC 成功终止,则所有其他 RANSAC 也会终止。最后,从所有线程同步最佳模型。如果使用 PROSAC 采样器,则线程必须共享相同的采样器,因为采样是顺序进行的。然而,使用框架的默认选项时,并行 RANSAC 不是确定的,因为它取决于每个线程运行的频率。确保它是确定性的最简单方法是使用无 SPRT 和局部优化的 PROSAC 采样器,并且不适用于基本矩阵,因为它们在内部使用随机生成器。
对于 NAPSAC,渐进 NAPSAC 或图剪切方法要求构建邻域图。在框架中,有 3 个选项可用于执行此操作
- NEIGH_FLANN_KNN – 估算邻域图,使用 OpenCV FLANN K 最近邻。KNN 的默认值是 7。KNN 方法可能非常适合采样,但不适合 GC-RANSAC。
NEIGH_FLANN_RADIUS
– 与上文所述类似,找到距离小于 20 像素的邻近点。
NEIGH_GRID
– 用哈希表查找单元格中网格点,来查找点邻域。这种方法在 [17] 中进行了描述。虽然速度大幅提升,但不如 NEIGH_FLANN_RADIUS
准确。
请注意,NEIGH_FLANN_RADIUS
和 NEIGH_FLANN_RADIUS
无法用 PnP 求解器,因为有 3D 对象点。
新标志
USAC_DEFAULT
– 具有标准 LO-RANSAC。
USAC_PARALLEL
– 具有同时运行的 LO-RANSAC 和 RANSAC。
USAC_ACCURATE
– 具有 GC-RANSAC。
USAC_FAST
– 具有 LO-RANSAC,在局部优化步骤中迭代次数更少。使用 RANSAC 得分来最大化内点的数量并尽早终止。
USAC_PROSAC
– 具有 PROSAC 采样。请注意,必须对点进行排序。
USAC_FM_8PTS
– 具有 LO-RANSAC。仅适用于具有 8 点求解器的基本矩阵。
USAC_MAGSAC
– 具有 MAGSAC++。
每个标志都使用 SPRT 验证。最后,通过非最小估计对找到的所有内点进行优化,获得最终最佳模型。
几个其他重要参数
randomGeneratorState
– 由于 OpenCV 中的每个 USAC 求解器都是确定性的(即对于相同的点和参数返回相同的结果),通过提供新的状态将输出新的模型。
loIterations
– 用于局部优化方法的迭代次数。默认值为 10。通过增加 loIterations
,输出模型可能会更准确,但是,计算时间也可能增加。
loSampleSize
– 用于局部优化方法的最大样本数。默认值为 14。请注意,通过增加 loSampleSize
,模型的准确度和计算时间也会增加。但是,建议将值保持在 100 以下,因为对较少数量的点进行估计更快且更健壮。
样本
opencv/samples 目录中有三个新的样本文件。
epipolar_lines.cpp
– main
函数的输入参数是两条图像路径。然后,使用 SIFT 检测器找到对应关系。使用从假定对应和极线图中 RANSAC 找到基本矩阵。
essential_mat_reconstr.cpp
– 输入参数为包含图像名称和单一内在矩阵的数据文件以及存储这些图像的目录的路径。使用 SIFT 找到对应关系。使用 RANSAC 估计本质矩阵,并将本质矩阵分解为旋转和平移。然后通过构建具有投影矩阵的两个相对姿态,将图像点三角测量为目标点。通过使用 3D 平面拟合运行 RANSAC,可以对目标点以及对应关系进行平面聚类。
essential_mat_reconstr.py
– 与 .cpp 文件中的功能相同,但是不是将点聚类到平面,而是绘制目标点的 3D 地图。