ransac算法_RANSAC直线拟合(五十)

论坛 期权论坛     
选择匿名的用户   2021-5-30 11:16   93   0
<div class="._5ce-wx-style" style="font-size:16px;">
<div class="rich_media_content" id="js_content">
  <p><img alt="9a5aab284dead063ee410acbe7cc402b.png" src="https://beijingoptbbs.oss-cn-beijing.aliyuncs.com/cs/5606289-e9f77df708668f0bed2c74990b561079.png"></p>
  <p>方法1:</p>
  <pre class="blockcode"><code>/*************************************************Author:  SayheyheyheyDate:2019-7-4Description:根据伪代码实现通用的RANSAC模板自定义线性模型,实现两种方式的直线拟合**************************************************/#include #include #include #include #include #include #include using namespace cv;#include using namespace std;//数据点类型struct st_point{<!-- -->  st_point(){};  st_point(double X, double Y) :x(X), y(Y){};  double x;  double y;};/*** &#64;brief 线性模型** Ax&#43;By&#43;C &#61; 0;*/class linearModel{<!-- -->public:  //待估计参数  double A, B, C;public:  linearModel(){};  ~linearModel(){};  //使用两个点对直线进行初始估计  void Update(vector &amp;data, set&lt;int&gt; &amp;maybe_inliers){<!-- -->    assert(maybe_inliers.size() &#61;&#61; 2);    //初始化的点不为2个,报错    //根据索引读取数据    vector&lt;int&gt; points(maybe_inliers.begin(), maybe_inliers.end());    st_point pts1 &#61; data[points[0]];    st_point pts2 &#61; data[points[1]];    //根据两个点计算直线参数(得到其中一组解,可以任意比例缩放)    double delta_x &#61; pts2.x - pts1.x;    double delta_y &#61; pts2.y - pts1.y;    A &#61; delta_y;    B &#61; -delta_x;    C &#61; -delta_y*pts2.x &#43; delta_x*pts2.y;  }  //返回点到直线的距离  double computeError(st_point point){<!-- -->    double numerator &#61; abs(A*point.x &#43; B*point.y &#43; C);    double denominator &#61; sqrt(A*A &#43; B*B);    return numerator / denominator;  }  //根据一致点的集合对直线进行重新估计  double Estimate(vector &amp;data, set&lt;int&gt; &amp;consensus_set){<!-- -->    assert(consensus_set.size() &gt;&#61; 2);    //求均值 means    double mX, mY;    mX &#61; mY &#61; 0;    //for (auto &amp;index: consensus_set){<!-- -->    for(int index &#61; 0; index &lt; consensus_set.size(); index&#43;&#43;)    {<!-- -->      mX &#43;&#61; data[index].x;      mY &#43;&#61; data[index].y;    }    mX /&#61; consensus_set.size();    mY /&#61; consensus_set.size();    //求二次项的和 sum    double sXX, sYY, sXY;    sXX &#61; sYY &#61; sXY &#61; 0;    //for (auto &amp;index : consensus_set){<!-- -->    for (int index &#61; 0; index &lt; consensus_set.size(); index&#43;&#43;)    {<!-- -->      st_point point;      point &#61; data[index];      sXX &#43;&#61; (point.x - mX)*(point.x - mX);      sYY &#43;&#61; (point.y - mY)*(point.y - mY);      sXY &#43;&#61; (point.x - mX)*(point.y - mY);    }        //解法1:求y&#61;kx&#43;b的最小二乘估计,然后再转换成一般形式    //参考 https://blog.csdn.net/hookie1990/article/details/91406309    bool isVertical &#61; sXY &#61;&#61; 0 &amp;&amp; sXX &lt; sYY;    bool isHorizontal &#61; sXY &#61;&#61; 0 &amp;&amp; sXX &gt; sYY;    bool isIndeterminate &#61; sXY &#61;&#61; 0 &amp;&amp; sXX &#61;&#61; sYY;    double k &#61; 0;    double b &#61; 0;    if (isVertical)    {<!-- -->    A &#61; 1;    B &#61; 0;    C &#61; mX;    }    else if (isHorizontal)    {<!-- -->    A &#61; 0;    B &#61; 1;    C &#61; mY;    }    else if (isIndeterminate)    {<!-- -->    A &#61; 0;    B &#61; 0;    C &#61; 0;    }    else    {<!-- -->    k &#61; (sYY - sXX &#43; sqrt((sYY - sXX) * (sYY - sXX) &#43; 4.0 * sXY * sXY)) / (2.0 * sXY);  //斜率    b &#61; mY - k * mX;                              //截距    //正则化项,使得A^2&#43;B^2 &#61; 1;    double normFactor &#61; 1 / sqrt(1 &#43; k*k);    A &#61; normFactor * k;    B &#61; -normFactor;    C &#61; normFactor*b;    }    //返回残差    if (isIndeterminate){<!-- -->    return 0;    }    double error &#61; A*A*sXX &#43; 2 * A*B*sXY &#43; B*B*sYY;    error /&#61; consensus_set.size();    return error;        解法2:    //if (sXX &#61;&#61; 0){<!-- -->    //  A &#61; 1;    //  B &#61; 0;    //  C &#61; -mX;    //}    //else{<!-- -->    //  A &#61; sXY / sXX;    //  B &#61; -1;    //  C &#61; mY - A*mX;    //  //归一化令A^2&#43;B^2 &#61; 1;    //  double normFactor &#61; sqrt(A*A &#43; B*B);    //  A /&#61; normFactor;    //  B /&#61; normFactor;    //  C /&#61; normFactor;    //}    //double error &#61; A*A*sXX &#43; 2 * A*B*sXY &#43; B*B*sYY;    //error /&#61; consensus_set.size();    //求平均误差    //return error;  }};/*** &#64;brief 运行RANSAC算法** &#64;param[in]  data  一组观测数据* &#64;param[in]  n    适用于模型的最少数据个数* &#64;param[in]  k    算法的迭代次数* &#64;param[in]  t    用于决定数据是否适应于模型的阀值* &#64;param[in]  d    判定模型是否适用于数据集的数据数目 * &#64;param[in&amp;out]  model  自定义的待估计模型,为该函数提供Update、computeError和Estimate三个成员函数*              运行结束后,模型参数被设置为最佳的估计值* &#64;param[out]  best_consensus_set  输出一致点的索引值* &#64;param[out]  best_error  输出最小损失函数*/template&lt;typename T, typename U&gt;int ransac(vector &amp;data, int n, int k, double t, int d,  U &amp;best_model, set&lt;int&gt; &amp;best_consensus_set, double &amp;best_error){<!-- -->  //1.初始化  int  it
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP