33、直线拟合

发布时间 2023-04-11 15:10:47作者: 夏蝉沐雪

OpenCV 4中提供了利用最小二乘M-estimator方法拟合直线的fitLine()函数,该函数的函数原型在代码清单7-7中给出。

代码清单7-7 fitLine()函数原型
1.    void cv::fitLine(InputArray  points,
2.                        OutputArray  line,
3.                        int  distType,
4.                        double  param,
5.                        double  reps,
6.                        double  aeps 
7.                        )
  • points:输入待拟合直线的2D或者3D点集。
  • line:输出描述直线的参数,2D点集描述参数为Vec4f类型,3D点集描述参数为Vec6f类型。
  • distType:M-estimator算法使用的距离类型标志,可以选择的距离类型在表7-1中给出。
  • param:某些类型距离的数值参数(C)。如果数值为0,则自动选择最佳值。
  • reps:坐标原点与直线之间的距离精度,数值0表示选择自适应参数,一般常选择0.01。
  • aeps:直线角度精度,数值0表示选择自适应参数,一般常选择0.01。

代码清单7-8 myFitLine.cpp直线拟合
1.    #include <opencv2\opencv.hpp>
2.    #include <iostream>
3.    #include <vector>
4.    
5.    using namespace cv;
6.    using namespace std;
7.    
8.    int main()
9.    {
10.        system("color F0");  //更改输出界面颜色
11.        Vec4f lines;  //存放你和后的直线
12.        vector<Point2f> point;  //待检测是否存在直线的所有点
13.        const static float Points[20][2] = {
14.            { 0.0f,   0.0f },{ 10.0f,  11.0f },{ 21.0f,  20.0f },{ 30.0f,  30.0f },
15.            { 40.0f,  42.0f },{ 50.0f,  50.0f },{ 60.0f,  60.0f },{ 70.0f,  70.0f },
16.            { 80.0f,  80.0f },{ 90.0f,  92.0f },{ 100.0f, 100.0f },{ 110.0f, 110.0f },
17.            { 120.0f, 120.0f },{ 136.0f, 130.0f },{ 138.0f, 140.0f },{ 150.0f, 150.0f },
18.            { 160.0f, 163.0f },{ 175.0f, 170.0f },{ 181.0f, 180.0f },{ 200.0f, 190.0f }
19.        };
20.        //将所有点存放在vector中,用于输入函数中
21.        for (int i = 0; i < 20; i++)
22.        {
23.            point.push_back(Point2f(Points[i][0], Points[i][1]));
24.        }
25.        //参数设置
26.        double param = 0;  //距离模型中的数值参数C
27.        double reps = 0.01;  //坐标原点与直线之间的距离精度
28.        double aeps = 0.01;  //角度精度
29.        fitLine(point, lines, DIST_L1, 0, 0.01, 0.01);
30.        double k = lines[1] / lines[0];  //直线斜率
31.        cout << "直线斜率:" << k << endl;
32.        cout << "直线上一点坐标x:" << lines[2] << ", y::" << lines[3] << endl;
33.        cout << "直线解析式:y=" << k << "(x-" << lines[2] << ")+" << lines[3] << endl;
34.        return 0;
35.    }