OpenCV (37): Fitting straight lines, triangles and circles

1.The meaning of point set fitting

       Point set fitting is a technique that approximately describes a given discrete data point by fitting a function or curve. In point set fitting, different functions or curve fitting methods can be used to fit straight lines, triangles, and circles. .

Line fitting : For a given set of two-dimensional data points, the least squares method can be used to fit a straight line.

Triangle Fitting : For a given set of two- or three-dimensional data points, triangle fitting methods can be used to find the best triangle that approximates the data points as closely as possible.

Circle Fitting : For a given set of two-dimensional data points, the circle fitting method can be used to find the circle that best matches the distribution of the data points.

2. Function fitLine() for fitting a straight line

void cv::fitLine ( InputArray   points,

OutputArray line,

int  distType,

double   param,

double    reps,

double     aeps

)

  • points: Input the 2D or 3D point set of the straight line to be fitted.
  • line: Output the parameters describing the straight line. The 2D point set description parameters are of Vec4f type, and the 3D point set description parameters are of Vec6f type. distType: The distance type flag used by the M-estimator algorithm.
  • param: Numeric parameter (C) for certain types of distance. If the value is 0, the best value is automatically selected.
  • reps: The distance accuracy between the coordinate origin and the straight line. A value of 0 indicates the selection of adaptive parameters. Generally, 0.01 is selected.
  • aeps: straight line angle accuracy, a value of 0 indicates the selection of adaptive parameters, generally 0.01 is selected.

Distance type selection flag

Sample code:

 //直线拟合
    Vec4f lines;//存放拟合后的直线
    vector<Point2f> point;//待检测是否存在直线的所有点
    const static float Points[20][2]={
            {0.0f,0.0f},{10.0f,11.0f},{21.0f,20.0f},{30.0f,30.0f},
            {40.0f,42.0f},{50.0f,50.0f},{60.0f,60.0f},{70.0f,70.0f},
            {80.0f,80.0f},{90.0f,92.0f},{100.0f,100.0f},{110.0f,110.0f},
            {120.0f,120.0f},{136.0f,130.0f},{138.0f,140.0f},{150.0f,150.0f},
            {160.0f,163.0f},{175.0f,170.0f},{181.0f,180.0f},{200.0f,190.0f},
    };
    //将所有点存放在vector中,用于输入函数中
    for(int i=0;i<20;i++){
        point.push_back(Point2f(Points[i][0],Points[i][1]));
    }
    //参数设置
    double param=0;//距离模型中的数值参数C
    double reps=0.01;//坐标原点与直线之间的距离精度
    double aeps=0.01;//角度精度
    fitLine(point,lines,DIST_L1,0,0.01,0.01);
    double k=lines[1]/lines[0];//直线斜率
    ostringstream ss;
    ss<<"直线效率:"<<k<<endl;
    ss<<"直线上一点坐标x:"<<lines[2]<<",y:"<<lines[3]<<endl;
    ss<<"直线解析式:y="<<k<<"(x-"<<lines[2]<<")+"<<lines[3]<<endl;
    LOGD("%s",ss.str().c_str());

operation result:

3. Function for fitting triangles minEnclosingTriangle()

double cv::minEnclosingTriangle ( InputArray points,OutputArray triangle)

  • points: The set of 2D points to be found surrounding the triangle
  • triangle: coordinates of the three vertices of the fitted triangle

4. Function minEnclosingTriangle() for fitting triangles

minEnclosingCircle()

void cv::minEnclosingCircle ( InputArray points,

Point2f &center,

float &radius

  • points: The set of 2D points to be found surrounding the circle
  • center: the center of a circle.
  • radius: radius of circle

Example code for fitting triangles and circles:

//点集拟合
void Point_set_fitting(){
  
    Mat img(500,500,CV_8UC3,Scalar::all(0));
    RNG &rng=theRNG();

    int i,count=rng.uniform(1,101);
    vector<Point> points;
    //生成随机点
    for(i=0;i<count;i++){
            Point  pt;
            pt.x=rng.uniform(img.cols/4,img.cols*3/4);
            pt.y=rng.uniform(img.rows/4,img.rows*3/4);
            points.push_back(pt);
    }
    //寻找包围点集的三角形
    vector<Point2f> triangle;
    double area= minEnclosingTriangle(points,triangle);
    //寻找包围点集的圆形
    Point2f center;
    float radius=0;
    minEnclosingCircle(points,center,radius);

    //创建两个图片用于输出结果
    img=Scalar ::all(0);
    Mat img2;
    img.copyTo(img2);
    //在图像中绘制坐标点
    for(i=0;i<count;i++){
        circle(img,points[i],3,Scalar(255,255,255),FILLED,LINE_AA);
        circle(img2,points[i],3,Scalar(255,255,255),FILLED,LINE_AA);
    }
    //绘制三角形
    for(i=0;i<3;i++){
        if(i==2){
            line(img,triangle[i],triangle[0],Scalar(255,255,255),1,16);
            break;
        }
        line(img,triangle[i],triangle[i+1],Scalar(255,255,255),1,16);
    }
    //绘制圆形
    circle(img2,center, cvRound(radius),Scalar(255,255,255),1,LINE_AA);

    //显示图像
    imwrite("/sdcard/DCIM/img.png",img);
    imwrite("/sdcard/DCIM/img2.png",img2);

}

Results of triangle fitting:

The result of circle fitting:

Guess you like

Origin blog.csdn.net/weixin_63357306/article/details/132817638