RANSAC在圖像拼接中有所使用,有時候也在圖像理解的相關算法中有所使用。
算法簡介如下(摘自《圖像處理、分析與機器視覺(第3版)》):
1.假設我們要將n個數據點X={x1,x1,...,xn}擬合為一個由至少m個點決定的模型(m<=n,對於直線,m=2)。(我這里實際是兩個不同均值、協方差高斯分布產生的數據)
2.設迭代計數k=1。
3.從X中隨機選取m個項並擬合一個模型。(我這里直線擬合,選了2個項)
4.給定偏差ε,計算X中相對於模型的殘差在偏差ε的個數,如果元素個數大於一個閾值t,根據一致點集重新擬合模型(可以利用最小二乘或其變種),算法終止。(我這里的偏差為1,閾值為數據個數的2/3)
5.設k=k+1,如果k小於一個事先給定的K,跳至第3步,否則采用具有迄今最大的一致點集模型,或算法失敗。
運行效果如下,紅圈是所有的數據,藍叉是符合擬合模型的數據。
matlab代碼如下:
main.m
close all;clear all;clc; %真實的數據 mu=[0 0]; %均值 S=[1 2.5;2.5 8]; %協方差 data1=mvnrnd(mu,S,200); %產生200個高斯分布數據 %噪聲數據 mu=[2 2]; S=[8 0;0 8]; data2=mvnrnd(mu,S,100); %產生100個噪聲數據 data=[data1;data2]; plot(data(:,1),data(:,2),'ro'); %顯示全部數據 K=100; %設置最大迭代次數 sigma=1; %設置擬合直線與數據距離的偏差 pretotal=0; %符合擬合模型的數據的個數 k=1; while pretotal < size(data,1)*2/3 && k<K %有2/3的數據符合擬合模型或達到最大迭代次數就可以退出了 SampIndex=floor(1+(size(data,1)-1)*rand(2,1)); %產生兩個隨機索引,找樣本用,floor向下取整 samp1=data(SampIndex(1),:); %對原數據隨機抽樣兩個樣本 samp2=data(SampIndex(2),:); line=Mytls([samp1;samp2]); %對兩個數據擬合出直線,或其他變種擬合方法 mask=abs(line*[data ones(size(data,1),1)]'); %求每個數據到擬合直線的距離 total=sum(mask<sigma); %計算數據距離直線小於一定閾值的數據的個數 if total>pretotal %找到符合擬合直線數據最多的擬合直線 pretotal=total; bestline=line; %找到最好的擬合直線 end k=k+1; end %顯示符合最佳擬合的數據 mask=abs(bestline*[data ones(size(data,1),1)]')<sigma; hold on; for i=1:length(mask) if mask(i) plot(data(i,1),data(i,2),'+'); end end
Mytls.m(已知兩點求直線)
%這里是解如下三個方程的方程組 %a*x1+b*y1+c=0 %a*x2+b*y2+c=0 %a^2+b^2=1 %返回系數[a b c] function line=Mytls(data) x = data(1, :); y = data(2, :); k=(y(1)-y(2))/(x(1)-x(2)); %直線斜率,有些情況肯定需要個別判斷,這里忽略了 a=sqrt(1-1/(1+k^2)); b=sqrt(1-a^2); if k>0 %如果斜率大於0,a,b異號 b=-b; end c=-a*x(1)-b*y(1); line=[a b c]; end
更詳盡的介紹見下面的網頁:
1.http://en.wikipedia.org/wiki/Ransac
2.http://www.cnblogs.com/xrwang/archive/2011/03/09/ransac-1.html