随机一致性检测RANSAC

来源:互联网 发布:淘宝上井江茶油造假 编辑:程序博客网 时间:2024/05/18 00:41

             随机一致性采样RANSAC是一种鲁棒的模型拟合算法,能够从有外点的数据中拟合准确的模型。

       它的原理很朴素就是从样本数据中找到具有一致性的数据,用这些数据去建立样本的数学模型。这个一致性怎么理解?我的理解是:如果按照聚类处理方式,一致性数据就是可以归为一类的数据,他们最相近。俗话说:物以类聚,人以群分。非我族类,其心必异。

       算法的详细原理及说明在维基上很详细,不赘述。维基上给的是一个直线随机一致性检测,而且还提供了Matlab演示代码,这个代码有几步关键的地方,由于是采用Matlab矩阵快速操作风格写的有点晦涩,当时我看这个代码后还做了些注解,后来维基采用了我的那部分注解。

       维基随机一致性算法网址:https://en.wikipedia.org/wiki/Random_sample_consensus

      下面是我根据算法原理利用Matlab进行直线的随机一致性检测,为了直观没用采用Matlab矩阵化的一些操作,速度上肯定是不太快的呀:

%%2016/11/12 by DQ clc;clear ;close all;
%数据的初始化m=100;data=zeros(2,m);data(1,:)=1:m;data(2,:)=100+20*rand(1,m);DataLen=length(data);DistThresh=4;InlierRatio=0.3;MinInlierNum=round(InlierRatio*DataLen);BestPointsNum=0;MaxIteration=200;Iter=0;x=data(1,:);y=data(2,:);%原始散点图OriginalScatterPlot=plot(x,y,'*');grid on;%Matlab 函数polyfit 最小二乘法拟合p=polyfit(x,y,1);x1=x;y1=polyval(p,x);hold on;PolyFitPlot=plot(x1,y1,'b');%RANSAC 执行过程,不断迭代while Iter<MaxIteration    %随机选取两个点,因为两个不同点确定一条直线啊    PreSelectIndex=randperm(DataLen,2);    P1=data(:,PreSelectIndex(1));    P2=data(:,PreSelectIndex(2));    P1x=P1(1);P1y=P1(2);    P2x=P2(1);P2y=P2(2);    %直线方程:A.x+B.y+C=0    A=P2y-P1y;    B=-(P2x-P1x);    C=P2x*P1y-P1x*P2y;    PointToLineDist=zeros(DataLen,1);    for i=1:DataLen        %点到直线的距离:d=(A*X+B*Y+C)/sqrt(A^2+B^2)        CurrentPoint=data(:,i);        X=CurrentPoint(1);        Y=CurrentPoint(2);        PointToLineDist(i)=abs(A*X+B*Y+C)/sqrt(A^2+B^2);    end    InlierIndex=find(PointToLineDist<=DistThresh);    InlierNum=length(InlierIndex);    if (InlierNum>BestPointsNum)&&(InlierNum>=MinInlierNum)        BestPointsSet=zeros(2,DataLen);        BestPointsNum=InlierNum;        BestPointsSet(:,InlierIndex)=data(:,InlierIndex);    end    Iter=Iter+1;endBestPointsSet(:,BestPointsSet(1,:)==0)=[];hold on;RANSACScatterPlot=plot(BestPointsSet(1,:),BestPointsSet(2,:),'ro');BestParameter = polyfit(BestPointsSet(1,:),BestPointsSet(2,:),1);xMin=min(data(1,:));xMax=max(data(1,:));x=xMin:0.5:xMax;%最佳直线方程y=BestParameter(1)*x+BestParameter(2);%画出直线方程hold on;RANSACLinePlot=plot(x,y,'r');title('RANSAC Find Best Line Fit Inlier');legend([OriginalScatterPlot,PolyFitPlot,RANSACScatterPlot,RANSACLinePlot],'OriginalScatter','PolyFit','RANSACScatter','RANSACLine');


原创粉丝点击