RANSAC
RANSAC(RAndom SAmple Consensus,随机采样一致)算法是从一组含有“外点”(outliers)的数据中正确估计数学模型参数的迭代算法。本文是关于 Sinkhorn 相关网络资料的整理。
1 简介
定义:
- RANSAC(RAndom SAmple Consensus,随机采样一致)算法是从一组含有“外点”(outliers)的数据中正确估计数学模型参数的迭代算法。
- “外点”一般指数据中的噪声,比如匹配中的误匹配和估计曲线中的离群点。所以,RANSAC 也是一种“外点”检测算法。
- RANSAC 算法是一种不确定算法,它只能在一种概率下产生结果,并且这个概率会随着迭代次数的增加而加大。
基本假设:
- 数据是由“内点”和“外点”组成的。“内点”就是组成模型参数的数据,“外点”就是不适合模型的数据。同时,RANSAC 假设:给定一组“内点”数据集合(通常较小),存在一个程序可以估计出符合“内点”的模型。
2 算法基本思想
基本思想:通过反复选择数据集去估计模型,一直迭代到估计出认为比较好的模型。
算法步骤-1:
- 随机地从数据集 中选择 个数据点,一般取 能刚好组成一个最小子集(满足模型估计的最小数据集,如直线拟合为 2 个点),以 个数据点估计待求模型;
- 根据前一步的模型,遍历 中的每一个数据点,判断是否满足这个模型,即是否在距离阈值 内:如果在,则为 inlier,将这个点加入 inlier 集合(一致集) 中;
- 如果 的大小大于阈值 ,则用 中的所有点重新估计模型,更新迭代次数 ,并结束算法循环;
- 如果 的大小小于阈值 ,选择一个新的最小子集 ,重复上述过程;
- 经过 次实验选择一个最大一致集 ,并用 的所有点重新估计模型。
算法步骤-2:
- 选择出可以估计出模型的最小数据集(对于直线拟合来说就是两个点,对于计算单应矩阵就是 4 个点);
- 使用这个数据集来计算出数据模型;
- 将所有数据带入这个模型,计算出 inlier 的数目(在一定误差范围内的适合当前迭代推出的模型的数据);
- 比较当前模型和之前推出的最好的模型的 inlier 的数量,记录最大 inlier 数的模型参数和 inlier 数;
- 重复 1-4 步,直到迭代结束或者当前模型足够好( inlier 数目大于一定数量)。
3 迭代次数推导
假设 inlier 在数据中的占比为 :
那么每次计算模型使用 个点的情况下,选取的点至少有一个 outlier 的概率为:
即在迭代 次的情况下, 就是 次迭代计算模型都至少采样到一个 outlier 去计算模型的概率。那么能采样到正确的 个点去计算出正确模型的概率就是:
从而求得迭代次数为:
- 通常是一个先验值。若事先不知道 的取值,则使用自适应迭代次数的方法:一开始设定一个无穷大的迭代次数,然后每次更新模型参数时,用当前的 inlier 比值作为 来估算迭代次数。
4 算法伪码
输入:
- data:观测数据
- model:适应于数据的模型
- n:适用于模型的最小数据个数
- k:算法的迭代次数
- t:用于决定数据是否适应于模型的阈值(判断是否为 inlier 的阈值)
- d:半段模型是否适用于数据集的 inlier 数目
输出:
- best_model:与数据最匹配的模型参数,没找到则返回 NULL
- best_consensus_set:估计出模型的数据点
- best_error:与数据相关的模型误差
算法:
1 | iterations = 0; |
5 用 Python 拟合直线
1 | import numpy as np |
6 ORB 中的 RANSAC 调用
1 |
|
7 OpenCV 对 RANSAC 的应用
7.1 findHomography()
1 | CV_EXPORTS_W |
参数说明:
-
srcPoints
:源平面的坐标矩阵,可以是CV_32FC2
类型,也可以是vector<Point2f>
类型。 -
dstPoints
:目标平面的坐标矩阵,可以是CV_32FC2
类型,也可以是vector<Point2f>
类型。 -
method
:计算单应矩阵所使用的方法。不同的方法对应不同的参数,具体如下:-
0
:利用所有点的常规方法;RANSAC
:基于 RANSAC 的鲁棒算法;LMEDS
:最小中值鲁棒算法;RHO
:基于 PROSAC 的鲁棒算法。
-
-
ransacReprojThreshold
:将点对视为内点的最大允许重投影错误阈值(仅用于 RANSAC 和 RHO 方法)。如果则点被认为是个 outlier(即错误匹配点对)。若
srcPoints
和dstPoints
是以像素为单位的,则该参数通常设置在 1 到 10 的范围内。 -
mask
:可选输出掩码矩阵,通常由鲁棒算法(RANSAC 或 LMEDS)设置。注意,输入掩码矩阵是不需要设置的。 -
maxIters
:RANSAC 算法的最大迭代次数,默认为 2000。 -
confidence
:可信度,取值为 。
7.2 findFundamental()
1 | CV_EXPORTS_W |
参数说明:
points1
:第一张图像的点;points2
:第二章图像的点;param1
:该参数用于 RANSAC 算法,它是从点到对极线的最大距离(以像素为单位),超过该距离,该点被视为异常值,并且不用于计算最终的基础矩阵。 可以将其设置为 1-3 ,具体取决于点定位的精度,图像分辨率和图像噪声。param2
:该参数仅在 RANSAC 算法以及 LMedS 算法中, 它指定了估计矩阵正确的期望置信度(概率)。
7.3
1 | bool cv::solvePnPRansac( |
参数说明:
objectPoints
:目标坐标系下的目标点, 或者 , 为点的数量,也可以是vector<Point3f>
。imagePoints
:目标对应的图像点, 或者 ,也可以是vector<Point2f>
。cameraMatrix
:相机内参矩阵。distCoeffs
:畸变参数向量,可以是 NULL 或 4、5、8、12 或 14 个变量组成的向量。rvec
:输出的旋转向量,结合tvec
将点从模型坐标系转换到相机坐标系。tvec
:输出的位移向量。useExtrinsicGauss
:使用在SOLVEPNP_INTERATIVE
的参数。若为true
,则函数使用提供的rvec
和tvec
作为旋转和平移的初始值。iterationsCount
:迭代次数。reprojectionError
:RANSAC 算法的 inlier 阈值,表示观测和估计点投影的最大距离阈值。confidence
:算法结果的置信度。inliers
:包含在objectPoints
和imagePoints
的 inlier 的索引。flags
:求解 PnP 的方法(见solvePnP()
)。