<span style="font-size:18px;">function testRansac()
% real model coef
k = .5;
b = 10;
ptNum = 200;
outlrRatio = .4; %非模型店的个数比率
inlrStd = 5; %距离模型点的距离
pts = genRansacTestPoints(ptNum,outlrRatio,inlrStd,[k b]);%%产生随机点 线性点和噪声点
figure,plot(pts(1,:),pts(2,:),'.'),hold on
%%
X = -ptNum/2:ptNum/2;
plot(X,k*X+b,'k')
err0 = sqrError(k,b,pts(:,1:ptNum*(1-outlrRatio))) %计算总的误差
%%
% RANSAC 用随机一致抽样的方法
iterNum = 300;
thDist = 2; %阈值距离
thInlrRatio = .1; %模型点的比率
[t,r] = ransac(pts,iterNum,thDist,thInlrRatio);
k1 = -tan(t);
b1 = r/cos(t);
plot(X,k1*X+b1,'r')
err1 = sqrError(k1,b1,pts(:,1:ptNum*(1-outlrRatio)))
% least square fitting
coef2 = polyfit(pts(1,:),pts(2,:),1);
k2 = coef2(1);
b2 = coef2(2);
plot(X,k2*X+b2,'g')
err2 = sqrError(k2,b2,pts(:,1:ptNum*(1-outlrRatio)))
end
function err = sqrError(k,b,pts)
% Calculate the square error of the fit
theta = atan(-k);
n = [cos(theta),-sin(theta)];
pt1 = [0;b];
err = sqrt(sum((n*(pts-repmat(pt1,1,size(pts,2)))).^2));
end</span>
<span style="font-size:18px;">function [ pts ] = genRansacTestPoints( ptNum,outlrRatio,inlrStd,inlrCoef )
%GENRANSACTESTPOINTS Generate the points used by RANSAC function
% PTS = GENRANSACTESTPOINTS(PTNUM,OUTLRRATIO,INLRSTD,INLRCOEF) PTS is
% 2*PTNUM, including PTNUM points, among which ROUND(OUTLRRATIO*PTNUM)
% are outliers, others are inliers.
% The inliers are around the line: y = INLRCOEF(1)*x + INLRCOEF(2),
% INLRSTD is the standard deviation of, the dist between inliers and the
% line. The outliers
outlrNum = round(outlrRatio*ptNum);%产生的非模型点的个数
inlrNum = ptNum-outlrNum; %模型点的个数
k = inlrCoef(1);
b = inlrCoef(2); %模型直线的斜率和截距
X = (rand(1,inlrNum)-.5)*ptNum; % X is in [-ptNum/2,ptNum/2] x的取值范围 在总点的范围内
Y = k*X+b; %直线上模型点的y值
% add noise for inliers
dist = randn(1,inlrNum)*inlrStd; %产生在点总数的正态随机分布的数
theta = atan(k); %直线的斜率
X = X+dist*(-sin(theta)); %接近模型的模型点的产生
Y = Y+dist*cos(theta); %x和y方向上的增量
inlrs = [X;Y];
outlrs = (rand(2,outlrNum)-.5)*ptNum;%费模型点的产生
% outlrs = (rand(2,outlrNum)-[ones(1,outlrNum)*.5;ones(1,outlrNum)*.1])*ptNum;
pts = [inlrs,outlrs];
end
</span>
随机一致抽样的过程<span style="font-size:18px;">function [ theta,rho ] = ransac( pts,iterNum,thDist,thInlrRatio )
%RANSAC Use RANdom SAmple Consensus to fit a line
% RESCOEF = RANSAC(PTS,ITERNUM,THDIST,THINLRRATIO) PTS is 2*n matrix including
% n points, ITERNUM is the number of iteration, THDIST is the inlier
% distance threshold and ROUND(THINLRRATIO*SIZE(PTS,2)) is the inlier number threshold. The final
% fitted line is RHO = sin(THETA)*x+cos(THETA)*y.
% Yan Ke @ THUEE, xjed09@gmail.com
sampleNum = 2;%采样个数
ptNum = size(pts,2);%点的个数
thInlr = round(thInlrRatio*ptNum); %要求的模型点的个数
inlrNum = zeros(1,iterNum);%存储每次迭代时模型点的个数
theta1 = zeros(1,iterNum);%每次迭代时计算出的直线角度
rho1 = zeros(1,iterNum); %每次迭代计算出的直线模型的截距
for p = 1:iterNum %进入迭代
% 1. fit using 2 random points
sampleIdx = randIndex(ptNum,sampleNum);%随机选择两个点
ptSample = pts(:,sampleIdx);
d = ptSample(:,2)-ptSample(:,1); %两个点的向量
d = d/norm(d); % direction vector of the line 直线的单位向量
% 2. count the inliers, if more than thInlr, refit; else iterate
n = [-d(2),d(1)]; % unit normal vector of the line
dist1 = n*(pts-repmat(ptSample(:,1),1,ptNum));%点到直线的距离 单位向量与计算点的向量内积
inlier1 = find(abs(dist1) < thDist);%找到不符合模型的点的距离的地址
inlrNum(p) = length(inlier1);%查看符合模型点的个数
if length(inlier1) < thInlr, continue; end
ev = princomp(pts(:,inlier1)'); %PCA变换
d1 = ev(:,1); %返回的系数
theta1(p) = -atan2(d1(2),d1(1)); % save the coefs
rho1(p) = [-d1(2),d1(1)]*mean(pts(:,inlier1),2); %
end
% 3. choose the coef with the most inliers
[~,idx] = max(inlrNum);%找到模型点最多的那个点集的参数
theta = theta1(idx);
rho = rho1(idx);
end</span>
代码的下载: