web-dev-qa-db-ja.com

OpenCVラインフィッティングアルゴリズム

OpenCV fitLine() アルゴリズムを理解しようとしています。

これはOpenCVからのコードの断片です:icvFitLine2D関数- icvFitLine2D

近似のためにポイントを選択し、ポイントからフィットしたラインまでの距離を(計算されたポイントで)計算し、他のポイントを選択し、chosen distTypeで距離を最小化しようとするランダム関数があることがわかります。

誰かが この瞬間 から何が起こるかを明確にすることができますか? OpenCVコードのコメントと変数名は、このコードを理解するのに役立ちません。

15
krzych

(これは古い質問ですが、主題は私の好奇心を刺激しました)

OpenCV FitLineは、2つの異なるメカニズムを実装しています。

パラメータdistTypeが_CV_DIST_L2_に設定されている場合、 標準の重み付けされていない最小二乗適合 が使用されます。

他のdistTypesのいずれかが使用されている場合(_CV_DIST_L1_、_CV_DIST_L12_、_CV_DIST_FAIR_、_CV_DIST_WELSCH_、_CV_DIST_HUBER_)、手順はある種のものですof [〜#〜] 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
_

重みは、選択したdistTypeに応じて、 マニュアル に従って計算されます。その式は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ノルム(unweighted最小二乗の合計は最小です)。これが正しいかどうかはわかりません。

23
HugoRune