2012-07-30 156 views
12

我想了解OpenCV fitLine()算法。OpenCV线拟合算法

这是从OpenCV的代码片断: icvFitLine2D功能 - icvFitLine2D

我看到有用来选择点近似一些随机函数,然后计算从点距离拟合线(带choosen分),然后选择其他点并尝试通过选择distType来最小化距离。

有人可以澄清从this moment会发生什么,没有硬数学,并假设没有伟大的统计知识? OpenCV代码注释和变量名称不能帮助我理解此代码。

回答

17

(这是一个老问题,但主题激起了我的好奇心)

在OpenCV FitLine implemements两种不同的机制。

如果参数distType设置为CV_DIST_L2,则使用standard unweighted least squares fit

如果使用其它distTypes之一(CV_DIST_L1CV_DIST_L12CV_DIST_FAIRCV_DIST_WELSCHCV_DIST_HUBER),那么该过程是某种RANSAC拟合:

  • 重复最多20次:
    • 挑选10个随机点,做适合他们的最小二乘方
    • 重复最多30次:
  • 返回最好的线装配

这是一个更详细的描述在pse udocode:

repeat at most 20 times: 

    RANSAC (line 371) 
    - pick 10 random points, 
    - set their weights to 1, 
    - set all other weights to 0 

    least squares weighted fit (fitLine2D_wods, line 381) 
    - fit only the 10 picked points to the line, using least-squares 

    repeat at most 30 times: (line 382) 
    - stop if the difference between the found solution and the previous found solution is less than DELTA (line 390 - 406) 
     (the angle difference must be less than adelta, and the distance beween the line centers must be less than rdelta) 
    - stop if the sum of squared distances between the found line and the points is less than EPSILON (line 407) 
     (The unweighted sum of squared distances is used here ==> the standard L2 norm) 

     re-calculate the weights for *all* points (line 412) 
     - using the given norm (CV_DIST_L1/CV_DIST_L12/CV_DIST_FAIR/...) 
     - normalize the weights so their sum is 1 
     - special case, to catch errors: if for some reason all weights are zero, set all weight to 1 

     least squares weighted fit (fitLine2D_wods, line 437) 
     - fit *all* points to the line, using weighted least squares 

    if the last found solution is better than the current best solution (line 440) 
     save it as the new best 
     (The unweighted sum of squared distances is used here ==> the standard L2 norm) 

     if the distance between the found line and the points is less than EPSILON 
      break 

return the best solution 

的权重取决于所选distType计算,根据the manual该公式是weight[Point_i] = 1/ p(distance_between_point_i_and_line),其中p为:

distType = CV_DIST_L1 enter image description here

distType = CV_DIST_L12 enter image description here

distType = CV_DIST_FAIR enter image description here

distType = CV_DIST_WELSCH enter image description here

distType = CV_DIST_HUBER enter image description here

不幸的是,我不知道哪个distType是最适合哪种类型的数据,也许有些人能揭示一些轻。


一些有趣的我注意到:所选择的范数仅用于迭代重新加权,所发现的那些中的最佳解决方案是根据所述L2范数(线总是挑选的量,未加权总和的至少正方形是最小的)。我不确定这是否正确。