cv::fitLine用法

Leon-發表於2020-11-21

定義

在opencv官方文件定義如下:

void cv::fitLine(InputArray points,
OutputArray line,
int distType,
double param,
double reps,
double aeps 
)

#include <opencv2/imgproc.hpp>
Fits a line to a 2D or 3D point set.

Parameters
points	Input vector of 2D or 3D points, stored in std::vector<> or Mat.
line	Output line parameters. In case of 2D fitting, it should be a vector of 4 elements (like Vec4f) - (vx, vy, x0, y0), where (vx, vy) is a normalized vector collinear to the line and (x0, y0) is a point on the line. In case of 3D fitting, it should be a vector of 6 elements (like Vec6f) - (vx, vy, vz, x0, y0, z0), where (vx, vy, vz) is a normalized vector collinear to the line and (x0, y0, z0) is a point on the line.
distType	Distance used by the M-estimator, see DistanceTypes
param	Numerical parameter ( C ) for some types of distances. If it is 0, an optimal value is chosen.
reps	Sufficient accuracy for the radius (distance between the coordinate origin and the line).
aeps	Sufficient accuracy for the angle. 0.01 would be a good default value for reps and aeps.

程式碼示例

簡而言之,就是利用已有的點擬合直線,本篇只針對使用做簡單示例,基於opencv3.4.5, C++;
主要介紹輸出引數,

  • OutputArray line:在二維下為四個元素,前兩個為向量(x, y),後兩個為擬合直線上的一個點
  • distType,參考如下:
    //! @see distanceTransform, fitLine
    enum DistanceTypes {
        DIST_USER    = -1,  //!< User defined distance
        DIST_L1      = 1,   //!< distance = |x1-x2| + |y1-y2|
        DIST_L2      = 2,   //!< the simple euclidean distance
        DIST_C       = 3,   //!< distance = max(|x1-x2|,|y1-y2|)
        DIST_L12     = 4,   //!< L1-L2 metric: distance = 2(sqrt(1+x*x/2) - 1))
        DIST_FAIR    = 5,   //!< distance = c^2(|x|/c-log(1+|x|/c)), c = 1.3998
        DIST_WELSCH  = 6,   //!< distance = c^2/2(1-exp(-(x/c)^2)), c = 2.9846
        DIST_HUBER   = 7    //!< distance = |x|<c ? x^2/2 : c(|x|-c/2), c=1.345
    };
    
  • param: 預設0,opencv自動優化
  • reps:0.01精度即可
  • aeps:建議0.01,0.01 would be a good default value…

y = x + 1直線

向量(0.707107,0.707107)如圖下
vcetor<0.707107, 0.707107>
設直線為 y = ax + b, a = 1 , b = 1
則 y = x + 1,部分程式碼:

    std::vector<cv::Point2f> input_pts;
    input_pts.emplace_back(1, 2);
    input_pts.emplace_back(2, 3);
    cv::Vec4f calc_line;
    cv::fitLine(input_pts, calc_line, cv::DIST_L2, 0, 0.01, 0.01);
    std::cout << "calc_line[0]=" << calc_line[0]
      << "\ncalc_line[0]=" << calc_line[1]
      << "\ncalc_line[0]=" << calc_line[2]
      << "\ncalc_line[0]=" << calc_line[3] << std::endl;

控制檯輸出

calc_line[0]=0.707107
calc_line[0]=0.707107
calc_line[0]=1.5
calc_line[0]=2.5

y = -x + 1直線

向量(0.707107,-0.707107)
vcetor<0.707107, -0.707107>
設直線為 y = ax + b, a = -1 , b = 1
則 y = -x + 1,部分程式碼:

    std::vector<cv::Point2f> input_pts;
    input_pts.emplace_back(1, 2);
    input_pts.emplace_back(2, 1);
    cv::Vec4f calc_line;
    cv::fitLine(input_pts, calc_line, cv::DIST_L2, 0, 0.01, 0.01);
    std::cout << "calc_line[0]=" << calc_line[0]
      << "\ncalc_line[0]=" << calc_line[1]
      << "\ncalc_line[0]=" << calc_line[2]
      << "\ncalc_line[0]=" << calc_line[3] << std::endl;
alc_line[0]=0.707107
calc_line[0]=-0.707107
calc_line[0]=1.5
calc_line[0]=1.5

Enjoy~

相關文章