隨機採樣一致性算法(一)初識

轉載自: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匹配:

第三步:圖像拼接,這個就涉及拼接技術了,直接給出結果:

參考

相關文章
相關標籤/搜索