• MATLAB 随机抽样一致RANSAC


    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

     1 close all;clear all;clc;
     2 
     3 %真实的数据
     4 mu=[0 0];  %均值
     5 S=[1 2.5;2.5 8];  %协方差
     6 data1=mvnrnd(mu,S,200);   %产生200个高斯分布数据
     7 
     8 %噪声数据
     9 mu=[2 2];
    10 S=[8 0;0 8];
    11 data2=mvnrnd(mu,S,100);     %产生100个噪声数据
    12 
    13 data=[data1;data2];
    14 plot(data(:,1),data(:,2),'ro');     %显示全部数据
    15 
    16 K=100;          %设置最大迭代次数
    17 sigma=1;        %设置拟合直线与数据距离的偏差
    18 pretotal=0;     %符合拟合模型的数据的个数
    19 k=1;
    20 while pretotal < size(data,1)*2/3 &&  k<K      %有2/3的数据符合拟合模型或达到最大迭代次数就可以退出了
    21     SampIndex=floor(1+(size(data,1)-1)*rand(2,1));  %产生两个随机索引,找样本用,floor向下取整
    22     
    23     samp1=data(SampIndex(1),:);     %对原数据随机抽样两个样本
    24     samp2=data(SampIndex(2),:);
    25     
    26     line=Mytls([samp1;samp2]);      %对两个数据拟合出直线,或其他变种拟合方法
    27     mask=abs(line*[data ones(size(data,1),1)]');    %求每个数据到拟合直线的距离
    28     total=sum(mask<sigma);              %计算数据距离直线小于一定阈值的数据的个数
    29     
    30     if total>pretotal            %找到符合拟合直线数据最多的拟合直线
    31         pretotal=total;
    32         bestline=line;          %找到最好的拟合直线
    33     end  
    34     k=k+1;
    35 end
    36 
    37 %显示符合最佳拟合的数据
    38 mask=abs(bestline*[data ones(size(data,1),1)]')<sigma;    
    39 hold on;
    40 for i=1:length(mask)
    41     if mask(i)
    42         plot(data(i,1),data(i,2),'+');
    43     end
    44 end

    Mytls.m(已知两点求直线)

     1 %这里是解如下三个方程的方程组
     2 %a*x1+b*y1+c=0
     3 %a*x2+b*y2+c=0
     4 %a^2+b^2=1
     5 %返回系数[a b c]
     6 function line=Mytls(data)
     7     x = data(1, :);
     8     y = data(2, :);
     9 
    10     k=(y(1)-y(2))/(x(1)-x(2));      %直线斜率,有些情况肯定需要个别判断,这里忽略了
    11     a=sqrt(1-1/(1+k^2));
    12     b=sqrt(1-a^2);
    13 
    14     if k>0          %如果斜率大于0,a,b异号
    15        b=-b; 
    16     end
    17     
    18     c=-a*x(1)-b*y(1);
    19     line=[a b c];
    20 end
  • 相关阅读:
    Oracle中优化SQL的原则(转贴)
    Oracle的分页查询
    Oracle中存储过程和Sql语句的优化重点
    oracle中sql语句的优化
    Oracle中优化SQL的原则(转贴)
    Oracle group by 用法实例详解
    Oracle中group by用法
    一本超越期待的 C++ 书——简评《Boost程序库完全开发指南:深入C++“准”标准库》
    以小见大——那些基于 protobuf 的五花八门的 RPC(2)
    BizTalk请求JAVA的Web Service报错
  • 原文地址:https://www.cnblogs.com/ybqjymy/p/13646594.html
Copyright © 2020-2023  润新知