目录
一、前言
RANSAC(RAndom SAmple Consensus,随机采样一致)算法常用于SLAM中特征点匹配,直接搜有不少这方面知识,这里不多介绍。在雷达中也同样有应用,只有想不到没有做不到,就是目标的航向估计,试想聚类后一个类中包含多个检测点,每个检测点都有自己的径向速度,但是具有相同的航向角,那么可以使用RANSAC算法对航向进行估计,这里记录RANSAC算法原理以便回忆。
动机:
假使需要从一个噪音较大的数据集中提取模型(比方说只有20%的数据时符合模型的)时,最小二乘法就不适用了,因为它只适合与误差较小的情况。
二、RASCAN理论
RANSAC(RAndom SAmple Consensus,随机采样一致)算法是从一组含有“外点”(outliers 无效数据)的数据中寻找内点(inliner 有效数据)正确估计数学模型参数的迭代算法。“外点”一般指的的数据中的噪声,比如说匹配中的误匹配和估计曲线中的离群点。所以,RANSAC也是一种“外点”检测算法。RANSAC算法是一种不确定算法,它只能在一种概率下产生结果,并且这个概率会随着迭代次数的增加而加大。
基本假设:在给定一组含有少部分“内点”的数据,存在一个程序可以估计出符合“内点”的模型
算法描述:
- 选择出可以估计出模型的最小数据集;(对于直线拟合来说就是两个点,对于计算Homography矩阵就是4个点);
- 使用这个数据集来计算出数据模型;
- 将所有数据带入这个模型,计算出“内点”的数目;(累加在一定误差范围内的适合当前迭代推出模型的数据);
- 比较当前模型和之前推出的最好的模型的“内点“的数量,记录最大“内点”数的模型参数和“内点”数;
- 重复1-4步,直到迭代结束或者当前模型已经足够好了(“内点数目大于一定数量”);
优点:能鲁棒的估计模型参数,噪声可以分布的任意广,可以远大于模型信息。
缺点:(1)它计算参数的迭代次数没有上限;如果设置迭代次数的上限,得到的结果可能不是最优的结果;(2)必须指定迭代次数作为收敛条件
三、估算迭代次数
假设“内点”在数据中的占比为 t
那么我们每次计算模型使用 个点的情况下,选取的点至少有一个外点的情况就是
总结:“内点”的概率 t 通常是一个先验值,为"内点"的比例。然后p为置信度,是我们希望RANSAC得到正确模型的概率 ;n为计算模型所需要的最少样本数=2;。如果事先不知道 t 的值,可以使用自适应迭代次数的方法。也就是一开始设定一个无穷大的迭代次数,然后每次更新模型参数估计的时候,用当前的“内点”比值 t 当成 来估算出迭代次数。
四、matlab实现
%step1. get data
clc
clear
close all
SIZE = 50;
X = linspace(0, 10, SIZE);
Y = 3 * X + 10;
random_x = X'+rand(SIZE,1)-0.5;
random_y = Y'+rand(SIZE,1)-0.5;
plot(random_x,random_y,'og','MarkerFaceColor','g');hold on;
for i=1:SIZE
random_x=[random_x;randi(10)];
random_y=[random_y;randi(30)+10];
end
plot(random_x(SIZE:end),random_y(SIZE:end),'ob','MarkerFaceColor','b');
sampleX= random_x;
sampleY= random_y;
%step2.RANSAC算法估算模型
%step2.1 初始值
%迭代最大次数,每次得到更好的估计会优化iters的数值
iters = 100000;
%数据和模型之间可接受的差值
sigma = 0.25;
%最好模型的参数估计和内点数目
best_a = 0;
best_b = 0;
pretotal = 0;
%希望的得到正确模型的概率
P = 0.99;
for i=1:iters
%step2.2随机在数据中选出两个点去求解模型,求解参数a,b
sample_indexs = randperm(SIZE * 2);
idx1=sample_indexs(randi(SIZE * 2));
idx2=sample_indexs(randi(SIZE * 2));
x1=sampleX(idx1);
y1=sampleY(idx1);
x2=sampleX(idx2);
y2=sampleY(idx2);
a = (y2 - y1) / (x2 - x1);
b = y1 - a * x1;
%step2.3 算出内点数目
total_inlier = 0;
for j=1:SIZE*2
if j ~= idx1 && j~=idx2
y_estimate = a*sampleX(j)+b;
if abs(y_estimate - sampleY(j))< sigma
total_inlier = total_inlier + 1;
end
end
end
%step2.4判断当前的模型是否比之前估算的模型好
if total_inlier > pretotal
pretotal = total_inlier;
t= pretotal/(SIZE*2);
iters = log10(1-P)/log10(1-t^2);
best_a =a;
best_b =b;
if t>=0.5 %判断是否当前模型已经符合超过一半的点
break;
end
end
end
Y_est = best_a*sampleX+best_b;
%step3 validation
plot(sampleX,Y_est,'-c','LineWidth',4);
参考:
RANSAC算法原理:
https://zhuanlan.zhihu.com/p/62238520