zoukankan      html  css  js  c++  java
  • 直线拟合算法(续)

    直线拟合算法(续)

    曾经写过一篇博客。介绍直线拟合算法。

    http://blog.csdn.net/liyuanbhu/article/details/50866802

    给出的代码事实上有一点小问题,就是 den = 0 时会出现除以 0 的错误。

    今天正好也有网友问起这个问题。

    我就再写一篇短文来说说怎样解决问题。

    首先我们知道:

    den=D2xy+(λDxx)2

    那么 den=0 意味着:

    Dxy=0λ=Dxx

    我们还有关于 λ 的计算式:

    λ=Dxx+Dyy(DxxDyy)2+4D2xy2

    带入后得到:

    DyyDxx=|DyyDxx|

    也就是要求DyyDxx

    有了这些就能够分析分析了。

    Dxy=0 说明xiyi是线性无关的。再往下还能够细分为 2 种情况。

    1. Dyy>Dxx 这时数据点落在一条垂直直线上,直线方程为 x=x¯
    2. Dyy=Dxx 数据均匀分布,找不到特殊的方向,无法拟合直线方程。

    依照这个分析。我们能够改进我们的代码:

    bool lineFit(const std::vector<cv::Point> &points, double &a, double &b, double &c)
    {
         int size = points.size();
         if(size < 2)
         {
             a = 0;
             b = 0;
             c = 0;
             return false;
         }
         double x_mean = 0;
         double y_mean = 0;
    
         for(int i = 0; i < size; i++)
         {
             x_mean += points[i].x;
             y_mean += points[i].y;
         }
         x_mean /= size;
         y_mean /= size; //至此。计算出了 x y 的均值
    
         double Dxx = 0, Dxy = 0, Dyy = 0;
    
         for(int i = 0; i < size; i++)
         {
             Dxx += (points[i].x - x_mean) * (points[i].x - x_mean);
             Dxy += (points[i].x - x_mean) * (points[i].y - y_mean);
             Dyy += (points[i].y - y_mean) * (points[i].y - y_mean);
         }
    
         double lambda = ( (Dxx + Dyy) - sqrt( (Dxx - Dyy) * (Dxx - Dyy) + 4 * Dxy * Dxy) ) / 2.0;
         double den = sqrt( Dxy * Dxy + (lambda - Dxx) * (lambda - Dxx) );
    
         if(fabs(den) < 1e-5)
         {
             if( fabs(Dxx / Dyy - 1) < 1e-5) //这时没有一个特殊的直线方向,无法拟合
             {
                 return false;
             }
             else
             {
                 a = 1;
                 b = 0;
                 c = - x_mean;
             }
         }
         else
         {
             a = Dxy / den;
             b = (lambda - Dxx) / den;
             c = - a * x_mean - b * y_mean;
         }
         return true;
    }
    
  • 相关阅读:
    using vb.net export a datatable to Excel and save as file
    selection sort with objective c
    stdin和STDIN_FILENO的区别
    stdin和STDIN_FILENO的区别
    linux系统kbhit的几种实现
    成为掌握企业聘用趋势的人才
    linux系统kbhit的几种实现
    c_lflag中ICANON的作用
    常量字符串的问题
    mmsbitfields gcc和vc关于位域那点事
  • 原文地址:https://www.cnblogs.com/cynchanpin/p/7231245.html
Copyright © 2011-2022 走看看