如何从一系列点计算线?

时间:2011-04-19 10:52:32

标签: algorithm image-recognition

可能是一个简单的问题,但到目前为止我找不到一个简单的解决方案。我正在为一个非常具体的用例开发一个简单的图像识别软件。

鉴于是一堆据说是直线的点。但是,有些点被错误地放置并远离线路。特别是在线的末端附近,点可能或多或少不准确。

示例:

   X            // this guy is off
         X      // this one even more
 X              // looks fine
 X
  X
      X         // a mistake in the middle
  X
     X          // another mistake, not as bad as the previous
   X
    X
   X
    X
         X      // we're off the line again

线的大致方向是已知的,在这种情况下,它是垂直的。实例中的实际线条实际上是垂直的,具有轻微的对角线斜率。

我只对无限线感兴趣(即它的斜率和偏移量),端点的位置并不重要。

作为附加信息(不确定是否重要),2个点不可能水平相邻。例如:

   X
   X
    X
   X X   // cannot happen
    X
     X

表现并不重要。我在C#工作,但我对任何语言都很好,或者只是一个通用的想法。

3 个答案:

答案 0 :(得分:4)

我认为你正在寻找Least squares fit via Linear Regression

答案 1 :(得分:3)

迈克很有见!使用以下内容:

double[] xVals = {...};
double[] yVals = {...};

double xMean = 0;
double yMean = 0;
double Sxy = 0;
double Sxx = 0;
double beta0, beta1;
int i;

for (i = 0; i < xVals.Length; i++)
{
   xMean += xVals[i]/xVals.Length;
   yMean += yVals[i]/yVals.Length;
}

for (i = 0; i < xVals.Length; i++)
{
   Sxy += (xVals[i]-xMean)*(yVals[i]-yMean);
   Sxx += (xVals[i]-xMean)*(xVals[i]-xMean);
}

beta1 = Sxy/Sxx;
beta0 = yMean-beta1*xMean;

使用beta1作为斜率,使用beta0作为y轴截距!

答案 2 :(得分:3)

如果您知道没有异常值,则线性回归(如其他人所述)很好。

如果你有异常值,那么我最喜欢的方法之一是中位数中值线方法: http://education.uncc.edu/droyster/courses/spring00/maed3103/Median-Median_Line.htm

基本上,您可以按X值对点进行排序,然后将点拆分为三个大小相等的组(最小值,中值和最大值)。最终斜率是通过小组中位数和大组中位数的线的斜率。中间组的中位数与其他中位数一起用于计算最终偏移/截距。

这是一个简单的算法,可以在几个图形计算器上找到。

通过取三个中位数,你完全忽略了任何异常值(在最左边,最右边,远边或远处)。

下图显示了具有几个大异常值的一组数据的线性回归和中位数 - 中值线。

Linear Regression vs. Median-Median