随机样本一致抽样
<span style="font-size:18px;">function testRansac()% real model coef
k = .5;
b = 10;
ptNum = 200;
outlrRatio = .4; %非模型店的個(gè)數(shù)比率
inlrStd = 5; %距離模型點(diǎn)的距離
pts = genRansacTestPoints(ptNum,outlrRatio,inlrStd,[k b]);%%產(chǎn)生隨機(jī)點(diǎn) 線性點(diǎn)和噪聲點(diǎn)
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))) %計(jì)算總的誤差
%%
% RANSAC 用隨機(jī)一致抽樣的方法
iterNum = 300;
thDist = 2; %閾值距離
thInlrRatio = .1; %模型點(diǎn)的比率
[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)))endfunction err = sqrError(k,b,pts)
% Calculate the square error of the fittheta = 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);%產(chǎn)生的非模型點(diǎn)的個(gè)數(shù)
inlrNum = ptNum-outlrNum; %模型點(diǎn)的個(gè)數(shù)k = inlrCoef(1);
b = inlrCoef(2); %模型直線的斜率和截距
X = (rand(1,inlrNum)-.5)*ptNum; % X is in [-ptNum/2,ptNum/2] x的取值范圍 在總點(diǎn)的范圍內(nèi)
Y = k*X+b; %直線上模型點(diǎn)的y值% add noise for inliers
dist = randn(1,inlrNum)*inlrStd; %產(chǎn)生在點(diǎn)總數(shù)的正態(tài)隨機(jī)分布的數(shù)
theta = atan(k); %直線的斜率
X = X+dist*(-sin(theta)); %接近模型的模型點(diǎn)的產(chǎn)生
Y = Y+dist*cos(theta); %x和y方向上的增量
inlrs = [X;Y];outlrs = (rand(2,outlrNum)-.5)*ptNum;%費(fèi)模型點(diǎn)的產(chǎn)生
% outlrs = (rand(2,outlrNum)-[ones(1,outlrNum)*.5;ones(1,outlrNum)*.1])*ptNum;
pts = [inlrs,outlrs];end
</span>
隨機(jī)一致抽樣的過(guò)程
<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.comsampleNum = 2;%采樣個(gè)數(shù) ptNum = size(pts,2);%點(diǎn)的個(gè)數(shù) thInlr = round(thInlrRatio*ptNum); %要求的模型點(diǎn)的個(gè)數(shù) inlrNum = zeros(1,iterNum);%存儲(chǔ)每次迭代時(shí)模型點(diǎn)的個(gè)數(shù) theta1 = zeros(1,iterNum);%每次迭代時(shí)計(jì)算出的直線角度 rho1 = zeros(1,iterNum); %每次迭代計(jì)算出的直線模型的截距for p = 1:iterNum %進(jìn)入迭代% 1. fit using 2 random pointssampleIdx = randIndex(ptNum,sampleNum);%隨機(jī)選擇兩個(gè)點(diǎn)ptSample = pts(:,sampleIdx);d = ptSample(:,2)-ptSample(:,1); %兩個(gè)點(diǎn)的向量d = d/norm(d); % direction vector of the line 直線的單位向量% 2. count the inliers, if more than thInlr, refit; else iteraten = [-d(2),d(1)]; % unit normal vector of the linedist1 = n*(pts-repmat(ptSample(:,1),1,ptNum));%點(diǎn)到直線的距離 單位向量與計(jì)算點(diǎn)的向量?jī)?nèi)積inlier1 = find(abs(dist1) < thDist);%找到不符合模型的點(diǎn)的距離的地址inlrNum(p) = length(inlier1);%查看符合模型點(diǎn)的個(gè)數(shù)if length(inlier1) < thInlr, continue; endev = princomp(pts(:,inlier1)'); %PCA變換d1 = ev(:,1); %返回的系數(shù)theta1(p) = -atan2(d1(2),d1(1)); % save the coefsrho1(p) = [-d1(2),d1(1)]*mean(pts(:,inlier1),2); % end% 3. choose the coef with the most inliers [~,idx] = max(inlrNum);%找到模型點(diǎn)最多的那個(gè)點(diǎn)集的參數(shù) theta = theta1(idx); rho = rho1(idx);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.comsampleNum = 2;%采樣個(gè)數(shù) ptNum = size(pts,2);%點(diǎn)的個(gè)數(shù) thInlr = round(thInlrRatio*ptNum); %要求的模型點(diǎn)的個(gè)數(shù) inlrNum = zeros(1,iterNum);%存儲(chǔ)每次迭代時(shí)模型點(diǎn)的個(gè)數(shù) theta1 = zeros(1,iterNum);%每次迭代時(shí)計(jì)算出的直線角度 rho1 = zeros(1,iterNum); %每次迭代計(jì)算出的直線模型的截距for p = 1:iterNum %進(jìn)入迭代% 1. fit using 2 random pointssampleIdx = randIndex(ptNum,sampleNum);%隨機(jī)選擇兩個(gè)點(diǎn)ptSample = pts(:,sampleIdx);d = ptSample(:,2)-ptSample(:,1); %兩個(gè)點(diǎn)的向量d = d/norm(d); % direction vector of the line 直線的單位向量% 2. count the inliers, if more than thInlr, refit; else iteraten = [-d(2),d(1)]; % unit normal vector of the linedist1 = n*(pts-repmat(ptSample(:,1),1,ptNum));%點(diǎn)到直線的距離 單位向量與計(jì)算點(diǎn)的向量?jī)?nèi)積inlier1 = find(abs(dist1) < thDist);%找到不符合模型的點(diǎn)的距離的地址inlrNum(p) = length(inlier1);%查看符合模型點(diǎn)的個(gè)數(shù)if length(inlier1) < thInlr, continue; endev = princomp(pts(:,inlier1)'); %PCA變換d1 = ev(:,1); %返回的系數(shù)theta1(p) = -atan2(d1(2),d1(1)); % save the coefsrho1(p) = [-d1(2),d1(1)]*mean(pts(:,inlier1),2); % end% 3. choose the coef with the most inliers [~,idx] = max(inlrNum);%找到模型點(diǎn)最多的那個(gè)點(diǎn)集的參數(shù) theta = theta1(idx); rho = rho1(idx);end</span>
代碼的下載:
點(diǎn)擊打開鏈接
總結(jié)
- 上一篇: 判断三维坐标系旋转正方向的简单方法
- 下一篇: Mat与IplImage*类型间的转换