OpenCV线拟合算法

krz*_*ych 15 algorithm statistics opencv curve-fitting

我正在尝试了解OpenCV fitLine()算法.

这是来自OpenCV的代码片段: icvFitLine2Dfunction - icvFitLine2D

我看到有一些随机函数选择点进行近似,然后计算从点到拟合线的距离(选择点),然后选择其他点并尝试最小化距离并选择distType.

有人可以澄清从没有硬数学并假设没有伟大的统计知识的这一刻发生的事情吗?OpenCV代码注释和变量名称无助于我理解这段代码.

Hug*_*une 23

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

OpenCV实现了FitLine两种不同的机制.

如果参数distType设置为CV_DIST_L2,则使用标准的未加权最小二乘拟合.

如果其他的一个distTypes被使用(CV_DIST_L1,CV_DIST_L12,CV_DIST_FAIR,CV_DIST_WELSCH,CV_DIST_HUBER),那么该过程是某种RANSAC拟合:

  • 最多重复20次:
    • 挑选10个随机点,仅对它们进行最小二乘拟合
    • 最多重复30次:
  • 返回找到的最佳线条

这是伪代码中更详细的描述:

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
Run Code Online (Sandbox Code Playgroud)

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

distType = CV_DIST_L1 在此输入图像描述

distType = CV_DIST_L12 在此输入图像描述

distType = CV_DIST_FAIR 在此输入图像描述

distType = CV_DIST_WELSCH 在此输入图像描述

distType = CV_DIST_HUBER 在此输入图像描述

不幸的是,我不知道哪种distType数据最适合哪种数据,也许其他人可以对此有所了解.


我注意到一些有趣的事情:选择的范数仅用于迭代重新加权,找到的最佳解决方案总是根据L2范数(未加权的最小二乘和最小的线)来选择.我不确定这是否正确.