C++ Opencv 最小二乘法直线拟合:y=kx+b

在这里插入图片描述

int LeastSquaresLineFit(cv::Mat srcImage, cv::Mat& dstImage, vector<Point> points, Mat& result)
{
	dstImage = srcImage.clone();
	//cv::cvtColor(dstImage, dstImage, COLOR_GRAY2BGR);
	for (int i = 0; i < points.size(); i++)
	{
		//在原图上画出点
		circle(dstImage, points[i], 3, Scalar(255, 0, 0), 1, 8);
	}
	//构建A矩阵 
	int N = 2;
	Mat A = Mat::zeros(N, N, CV_64FC1);

	for (int row = 0; row < A.rows; row++)
	{
		for (int col = 0; col < A.cols; col++)
		{
			for (int k = 0; k < points.size(); k++)
			{
				A.at<double>(row, col) = A.at<double>(row, col) + pow(points[k].x, row + col);
			}
		}
	}
	//构建B矩阵
	Mat B = Mat::zeros(N, 1, CV_64FC1);
	for (int row = 0; row < B.rows; row++)
	{

		for (int k = 0; k < points.size(); k++)
		{
			B.at<double>(row, 0) = B.at<double>(row, 0) + pow(points[k].x, row) * points[k].y;
		}
	}
	//A*X=B
	Mat X;
	//cout << A << endl << B << endl;
	solve(A, B, X, DECOMP_LU);
	cout << "[k;b]=" << X << endl;
	result = X;
	vector<Point>lines;
	for (int x = 0; x < srcImage.size().width; x++)
	{				// y = b + ax;
		double y = X.at<double>(0, 0) + X.at<double>(1, 0) * x;
		printf("(%d,%lf)\n", x, y);
		lines.push_back(Point(x, y));
	}
	polylines(dstImage, lines, false, Scalar(0, 0, 255), 1, 8);
	//namedWindow("srcImageLine",0);
	//imshow("srcImageLine", dstImage);

	return 0;

}

例子调用:

vector<Point>points;
//(27 39) (8 5) (8 9) (16 22) (44 71) (35 44) (43 57) (19 24) (27 39) (37 52)
points.push_back(Point(27, 39));
points.push_back(Point(8, 5));
points.push_back(Point(8, 9));
points.push_back(Point(16, 22));
points.push_back(Point(44, 71));
points.push_back(Point(35, 44));
points.push_back(Point(43, 57));
points.push_back(Point(19, 24));
points.push_back(Point(27, 39));
points.push_back(Point(37, 52));
Mat src = Mat(400, 400, CV_8UC3,Scalar(255,255,255));
Mat dstImage, result;
LeastSquaresLineFit(src, dstImage, points, result);
imwrite("a4.jpg", dstImage);
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

向日葵xyz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值