ransac算法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/itworld123/article/details/79097214
2018-01-18   创建人:Ruo_Xiao
开发环境:Matlab 2010
邮箱:[email protected]
  1. RANSAC是“RANdom SAmple Consensus(随机抽样一致)”的缩写。
  2. 使用条件:
    (1)大部分数据满足一定模型(局内点),例如:都在一条直线上。
    (2)局外点:不在这条直线上。产生的原因有:极值噪声等。
  3. 基本原理:以二维平面拟合直线方程为例
    随即找到两个点组成一条直线,计算其他所有的点与这条直线的距离,太大则抛弃,否则认为该点在直线上,最后统计直线上的点的数量。遍历所有点组合,直线上点的数量最多的组合就是真正的直线。
  4. 源码:
%ransan测试函数

%生成n个随机样本点
clear all;
clc
a = 1; b = 0; n = 30;
x = linspace(0,30,n);
y = a*x + b + rand(1,n);

%添加误差点
xx=[12,13,14,15,50];
yy=[2,1,5,2,18];
datax=[x,xx];
datay=[y,yy];


%直接用最小二乘进行拟合
p = polyfit(datax, datay, 1);

%用RANSAC方法进行拟合
k = 800; t = 0.1; d = n * 0.8;

p1 = ransac(datax,datay,k,t,d);

%图形结果
figure(1)
plot(datax, datay,'k.');
px = linspace(0,30,1000);
py = p(1)*px+p(2);
p1y= p1(1)*px+p1(2);
figure(1)
hold on
plot(px, py,'b');
hold on
plot(px, p1y,'r');
function p1 = ransac(datax,datay,k,t,d)
% k 是循环的最多次数
% t 阈值
% d 概率数 多少点落入拟合的线周围,超过该概率,直接认为找到了真正的直线。

max_num = 0;
i = 0;
number=  length(datax);

while i<k && max_num < d
    i = i+1;
    %随机产生两个点
    tt = unidrnd(number);
    ss = mod(unidrnd(number),number)+1;
    x1 = datax(tt);
    y1 = datay(tt);
    x2 = datax(ss);
    y2 = datay(ss);
    if x1 == x2
        continue;
    end
    %计算一些参数
    %y = kx+b;
    slope = (y2 - y1)/(x2 - x1);   %k
    ytrunc = y2 - x2 * slope;   %b
    %t是斜边,slope/(1+slope^2)^0.5是sin,故delta就是y方向上的距离阈值。
    delta = t*slope/(1+slope^2)^0.5;  
    count = 0;
    %遍历所有的点,若距离小于t,将其加入。
    for index=1:number
        %实际点的x0带入直线中,得到的y1,实际点的y0若满足:(y1 - delta) < y0 < (y1 +
        %delta),则认为该点是在线上的。
        if datay(index) < datax(index)*slope +ytrunc+ delta && datay(index) > datax(index)*slope +ytrunc - delta
            count = count + 1;
            result_point(count) = index;
        end
    end
    
     %计算内点的个数
    if(count > max_num)
        result_point1 = result_point;
        max_num = count;
        ms = ss;
        mt = tt;
    end

end
%用选取有效点进行拟合
p1 = polyfit(datax(result_point1(1:max_num)), datay(result_point1(1:max_num)), 1); 
end

结果:
这里写图片描述

猜你喜欢

转载自blog.csdn.net/itworld123/article/details/79097214
今日推荐