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

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

直线拟合
直线拟合

二,源码

//开始
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;
}

欢迎扫码关注我的微信公众号

在这里插入图片描述

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
OpenCV提供了直线拟合函数fitLine,可以用于拟合多条直线。该函数的原型如下: void fitLine(InputArray points, OutputArray line, int distType, double param, double reps, double aeps); 其中,points是输入的坐标点集合,line是输出的拟合直线的参数,distType是距离类型,param是距离参数,reps是拟合精度,aeps是角度精度。 要进行多条直线拟合,可以将多组坐标点分别传入fitLine函数进行拟合,得到对应的直线参数。可以使用std::vector<cv::Point>来存储每组坐标点,然后循环调用fitLine函数进行拟合。 以下是一个示例代码,用于拟合多条直线: std::vector<std::vector<cv::Point>> pointSets; // 存储多组坐标点 std::vector<cv::Vec4f> lines; // 存储拟合直线的参数 // 循环拟合每组坐标点 for (int i = 0; i < pointSets.size(); i++) { cv::Mat pointsMat(pointSets\[i\]); cv::Vec4f line; cv::fitLine(pointsMat, line, cv::DIST_L2, 0, 0.01, 0.01); lines.push_back(line); } 这样,lines中就存储了拟合得到的多条直线的参数。每个直线的参数是一个cv::Vec4f,其中前两个元素表示直线上的一个点,后两个元素表示直线的方向向量。 请注意,拟合直线的精度参数reps和aeps可以根据实际需求进行调整,以获得更好的拟合效果。 #### 引用[.reference_title] - *1* *2* *3* [OpenCV 学习(直线拟合)](https://blog.csdn.net/liyuanbhu/article/details/50193947)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值