基于opencv3.0的直线拟合和曲线拟合

来源:互联网 发布:2010年流行网络歌曲 编辑:程序博客网 时间:2024/05/22 03:31

一,拟合效果图
曲线拟合
曲线拟合,另外画了折线图

直线拟合
直线拟合

二,源码

//开始void CLeastSquaresMethodDlg::OnBnClickedStartButton(){    //创建用于绘制的深蓝色背景图像      int i_pointNum = 12;    cv::Mat image = cv::Mat::zeros(480, 640, CV_8UC3);    image.setTo(cv::Scalar(0, 100, 0));    //输入拟合点        std::vector<cv::Point> points;    points.push_back(cv::Point(100., 58.));    points.push_back(cv::Point(150., 70.));    points.push_back(cv::Point(200., 90.));    points.push_back(cv::Point(252., 140.));    points.push_back(cv::Point(300., 220.));    points.push_back(cv::Point(350., 400.));    points.push_back(cv::Point(400., 458.));    points.push_back(cv::Point(153., 79.));    points.push_back(cv::Point(240., 110.));    points.push_back(cv::Point(272., 170.));    points.push_back(cv::Point(330., 260.));    points.push_back(cv::Point(380., 460.));    //将拟合点绘制到空白图上        for (int i = 0; i < points.size(); i++)    {        cv::circle(image, points[i], 5, cv::Scalar(0, 0, 255), 2, 8, 0);    }    //绘制折线      cv::polylines(image, points, false, cv::Scalar(255, 0, 0), 2, 8, 0);    cv::Mat A;    //多项式拟合曲线    polynomial_curve_fit(points, 3, A);    //fitLine(points, A, CV_DIST_L2, 0, 0.01, 0.01);    //std::cout << "A = " << A << std::endl;    std::vector<cv::Point> points_fitted;    for (int x = 0; x < 400; x++)    {        double y = A.at<double>(0, 0) + A.at<double>(1, 0) * x +            A.at<double>(2, 0)*std::pow(x, 2) + A.at<double>(3, 0)*std::pow(x, 3);        points_fitted.push_back(cv::Point(x, y));    }    //折线拟合    cv::polylines(image, points_fitted, false, cv::Scalar(0, 255, 255), 1, 8, 0);    cv::imshow("曲线拟合", image);    //#####直线拟合#####################################################################    float d, t;    Mat img2 = Mat::zeros(480, 640, CV_8UC3);    img2.setTo(cv::Scalar(0, 100, 0));    Mat pointMat2 = Mat(1, i_pointNum, CV_32FC1);    // find the optimal line 曲线拟合      fitLine(points, pointMat2, CV_DIST_L1, 1, 0.001, 0.001);    float x0 = pointMat2.at<float>(0,0);    float y0 = pointMat2.at<float>(1,0);    float x1 = pointMat2.at<float>(2,0);    float y1 = pointMat2.at<float>(3,0);    //画出点      for (int i = 0; i < i_pointNum; i++)    {        circle(img2, points[i], 5, cv::Scalar(0, 0, 255), 2, 8, 0);    }    // 延长线至图像两端      d = 1;  //line[0 & 1]存储的是单位向量,所以d=1      //printf("\n %f\n", d);      //pointMat2.at<0, 0> /= d;    //pointMat2.at<0, 0> /= d;    //画出线段的两个端点(避免线太短,以线上一个随机点向两侧延伸line[0]*t )      Point pt1, pt2;    t = (float)(img2.cols + img2.rows);    pt1.x = cvRound(pointMat2.at<float>(2, 0) - pointMat2.at<float>(0, 0) * t);    pt1.y = cvRound(pointMat2.at<float>(3, 0) - pointMat2.at<float>(1, 0) * t);    pt2.x = cvRound(pointMat2.at<float>(2, 0) + pointMat2.at<float>(0, 0) * t);    pt2.y = cvRound(pointMat2.at<float>(3, 0) + pointMat2.at<float>(1, 0) * t);    //产生线    //MyLine(img2, Point(points2[0].x, points2[0].y), Point(points2[5].x, points2[5].y));    //line(img2,Point(points[1].x, points[1].y),Point(points[4].x, points[4].y),Scalar(0, 255, 0),2,8);    line(img2, Point(pt1.x, pt1.y), Point(pt2.x, pt2.y), Scalar(0, 255, 0), 2, 8);    imshow("直线拟合", img2);    //#####直线拟合#####################################################################    waitKey(0);    //cvDestroyWindow("直线拟合");    DestroyWindow();    //return 0;}
原创粉丝点击