轉載自:http://www.cnblogs.com/xingshansi/p/6763668.html
html
前言算法
理解最小二乘、霍夫變換、RANSAC在直線擬合上的區別。昨天梳理了霍夫變換,今天打算抽空梳理一下RANSAC算法,主要包括:dom
1)RANSAC理論介紹性能
2)RANSAC應用簡介;學習
內容爲本身的學習記錄,其中不少地方借鑑了別人,最後一塊兒給出連接。ui
1、RANSAC理論介紹this
普通最小二乘是保守派:在現有數據下,如何實現最優。是從一個總體偏差最小的角度去考慮,儘可能誰也不得罪。spa
RANSAC是改革派:首先假設數據具備某種特性(目的),爲了達到目的,適當割捨一些現有的數據。.net
給出最小二乘擬合(紅線)、RANSAC(綠線)對於一階直線、二階曲線的擬合對比:3d
能夠看到RANSAC能夠很好的擬合。RANSAC能夠理解爲一種採樣的方式,因此對於多項式擬合、混合高斯模型(GMM)等理論上都是適用的。
RANSAC的算法大體能夠表述爲(來自wikipedia):
Given: data – a set of observed data points model – a model that can be fitted to data points n – the minimum number of data values required to fit the model k – the maximum number of iterations allowed in the algorithm t – a threshold value for determining when a data point fits a model d – the number of close data values required to assert that a model fits well to data Return: bestfit – model parameters which best fit the data (or nul if no good model is found) iterations = 0 bestfit = nul besterr = something really large while iterations < k { maybeinliers = n randomly selected values from data maybemodel = model parameters fitted to maybeinliers alsoinliers = empty set for every point in data not in maybeinliers { if point fits maybemodel with an error smaller than t add point to alsoinliers } if the number of elements in alsoinliers is > d { % this implies that we may have found a good model % now test how good it is bettermodel = model parameters fitted to all points in maybeinliers and alsoinliers thiserr = a measure of how well model fits these points if thiserr < besterr { bestfit = bettermodel besterr = thiserr } } increment iterations } return bestfit
RANSAC簡化版的思路就是:
第一步:假定模型(如直線方程),並隨機抽取Nums個(以2個爲例)樣本點,對模型進行擬合:
第二步:因爲不是嚴格線性,數據點都有必定波動,假設容差範圍爲:sigma,找出距離擬合曲線容差範圍內的點,並統計點的個數:
第三步:從新隨機選取Nums個點,重複第一步~第二步的操做,直到結束迭代:
第四步:每一次擬合後,容差範圍內都有對應的數據點數,找出數據點個數最多的狀況,就是最終的擬合結果:
至此:完成了RANSAC的簡化版求解。
這個RANSAC的簡化版,只是給定迭代次數,迭代結束找出最優。若是樣本個數很是多的狀況下,難不成一直迭代下去?其實RANSAC忽略了幾個問題:
- 每一次隨機樣本數Nums的選取:如二次曲線最少須要3個點肯定,通常來講,Nums少一些易得出較優結果;
- 抽樣迭代次數Iter的選取:即重複多少次抽取,就認爲是符合要求從而中止運算?太多計算量大,太少性能可能不夠理想;
- 容差Sigma的選取:sigma取大取小,對最終結果影響較大;
這些參數細節信息參考:維基百科。
RANSAC的做用有點相似:將數據一切兩段,一部分是本身人,一部分是敵人,本身人留下商量事,敵人趕出去。RANSAC開的是家庭會議,不像最小二乘老是開全體會議。
附上最開始一階直線、二階曲線擬合的code(只是爲了說明最基本的思路,用的是RANSAC的簡化版):
一階直線擬合:
1 %隨機一致性採樣 2 clc;clear all;close all; 3 set(0,'defaultfigurecolor','w'); 4 %Generate data 5 param = [3 2]; 6 npa = length(param); 7 x = -20:20; 8 noise = 3 * randn(1, length(x)); 9 y = param*[x; ones(1,length(x))]+3*randn(1,length(x)); 10 data = [x randi(20,1,30);... 11 y randi(20,1,30)]; 12 %figure 13 figure 14 subplot 121 15 plot(data(1,:),data(2,:),'k*');hold on; 16 %Ordinary least square mean 17 p = polyfit(data(1,:),data(2,:),npa-1); 18 flms = polyval(p,x); 19 plot(x,flms,'r','linewidth',2);hold on; 20 title('最小二乘擬合'); 21 %Ransac 22 Iter = 100; 23 sigma = 1; 24 Nums = 2;%number select 25 res = zeros(Iter,npa+1); 26 for i = 1:Iter 27 idx = randperm(size(data,2),Nums); 28 if diff(idx) ==0 29 continue; 30 end 31 sample = data(:,idx); 32 pest = polyfit(sample(1,:),sample(2,:),npa-1);%parameter estimate 33 res(i,1:npa) = pest; 34 res(i,npa+1) = numel(find(abs(polyval(pest,data(1,:))-data(2,:))<sigma)); 35 end 36 [~,pos] = max(res(:,npa+1)); 37 pest = res(pos,1:npa); 38 fransac = polyval(pest,x); 39 %figure 40 subplot 122 41 plot(data(1,:),data(2,:),'k*');hold on; 42 plot(x,flms,'r','linewidth',2);hold on; 43 plot(x,fransac,'g','linewidth',2);hold on; 44 title('RANSAC');
二階曲線擬合:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
clc
;
clear
all
;
set
(0,
'defaultfigurecolor'
,
'w'
);
%Generate data
param = [3 2 5];
npa =
length
(param);
x = -20:20;
y = param*[x.^2;x;
ones
(1,
length
(x))]+3*
randn
(1,
length
(x));
data = [x
randi
(20,1,30);...
y
randi
(200,1,30)];
%figure
subplot
223
plot
(data(1,:),data(2,:),
'k*'
);
hold
on;
%Ordinary least square mean
p =
polyfit
(data(1,:),data(2,:),npa-1);
flms =
polyval
(p,x);
plot
(x,flms,
'r'
,
'linewidth'
,2);
hold
on;
title
(
'最小二乘擬合'
);
%Ransac
Iter = 100;
sigma = 1;
Nums = 3;
%number select
res =
zeros
(Iter,npa+1);
for
i
= 1:Iter
idx =
randperm
(
size
(data,2),Nums);
if
diff
(idx) ==0
continue
;
end
sample = data(:,idx);
pest =
polyfit
(sample(1,:),sample(2,:),npa-1);
%parameter estimate
res(
i
,1:npa) = pest;
res(
i
,npa+1) =
numel
(
find
(
abs
(
polyval
(pest,data(1,:))-data(2,:))<sigma));
end
[~,pos] =
max
(res(:,npa+1));
pest = res(pos,1:npa);
fransac =
polyval
(pest,x);
%figure
subplot
224
plot
(data(1,:),data(2,:),
'k*'
);
hold
on;
plot
(x,flms,
'r'
,
'linewidth'
,2);
hold
on;
plot
(x,fransac,
'g'
,
'linewidth'
,2);
hold
on;
title
(
'RANSAC'
);
|
2、RANSAC應用簡介
RANSAC其實就是一種採樣方式,例如在圖像拼接(Image stitching)技術中:
第一步:預處理後(聽說桶形變換,沒有去了解過)提取圖像特徵(如SIFT)
第二步:特徵點進行匹配,可利用歸一化互相關(Normalized Cross Correlation method, NCC)等方法。
但這個時候會有不少匹配錯誤的點:
這就比如擬合曲線,有不少的偏差點,這個時候就想到了RANSAC算法:我不要再兼顧全部了,每次選取Nums個點匹配 → 計算匹配後容差範圍內的點數 → 重複實驗,迭代結束後,找出點數最多的狀況,就是最優的匹配。
利用RANSAC匹配:
第三步:圖像拼接,這個就涉及拼接技術了,直接給出結果:
參考: