基于Opencv的最小二乘法拟合圆及椭圆

Opencv最小二乘拟合圆源代码:

 

Point3f LeastSquareFittingCircle(vector<Point2f> temp_coordinates)//利用opencv solve函数的高斯消元算法(LU分解)解方程组
{
	float x1 = 0;
	float x2 = 0;
	float x3 = 0;
	float y1 = 0;
	float y2 = 0;
	float y3 = 0;
	float x1y1 = 0;
	float x1y2 = 0;
	float x2y1 = 0;
	int num;
	vector<Point2f>::iterator k;
	Point3f tempcircle;
	num = temp_coordinates.size();
	for (k = temp_coordinates.begin(); k != temp_coordinates.end(); k++)
	{

		x1 = x1 + (*k).x;
		x2 = x2 + (*k).x * (*k).x;
		x3 = x3 + (*k).x * (*k).x * (*k).x;
		y1 = y1 + (*k).y;
		y2 = y2 + (*k).y * (*k).y;
		y3 = y3 + (*k).y * (*k).y * (*k).y;
		x1y1 = x1y1 + (*k).x * (*k).y;
		x1y2 = x1y2 + (*k).x * (*k).y * (*k).y;
		x2y1 = x2y1 + (*k).x * (*k).x * (*k).y;
	}
	Mat left_matrix = (Mat_<float>(3,3) << x2, x1y1, x1, x1y1, y2, y1, x1, y1, num);
	cout << "left_matrix=" << left_matrix << endl;
	Mat right_matrix = (Mat_<float>(3, 1) << -(x3 + x1y2), -(x2y1 + y3), -(x2 + y2));
	cout << "right_matrix=" << right_matrix << endl;
	Mat solution(3,1,CV_32F);
	solve(left_matrix, right_matrix, solution,CV_LU);
	cout << "solution=" << solution << endl;
	float a, b, c;
	a = solution.at<float>(0);
	b = solution.at<float>(1);
	c = solution.at<float>(2);
	tempcircle.x = -a / 2; //圆心x坐标
	tempcircle.y = -b / 2;//圆心y坐标
	tempcircle.z = sqrt(a*a + b*b - 4 * c) / 2;//圆心半径
	return tempcircle;
}
Point3f LeastSquareFittingCircle(vector<Point2f> temp_coordinates)//高斯消元法直接求解方程组
{
	float x1 = 0;
	float x2 = 0;
	float x3 = 0;
	float y1 = 0;
	float y2 = 0;
	float y3 = 0;
	float x1y1 = 0;
	float x1y2 = 0;
	float x2y1 = 0;
	int num;
	vector<Point2f>::iterator k;
	Point3f tempcircle;
	for (k = temp_coordinates.begin(); k != temp_coordinates.end(); k++)
	{

		x1 = x1 + (*k).x;
		x2 = x2 + (*k).x * (*k).x;
		x3 = x3 + (*k).x * (*k).x * (*k).x;
		y1 = y1 + (*k).y;
		y2 = y2 + (*k).y * (*k).y;
		y3 = y3 + (*k).y * (*k).y * (*k).y;
		x1y1 = x1y1 + (*k).x * (*k).y;
		x1y2 = x1y2 + (*k).x * (*k).y * (*k).y;
		x2y1 = x2y1 + (*k).x * (*k).x * (*k).y;
	}
	float C, D, E, G, H, a, b, c;
	num = temp_coordinates.size();
	C = num*x2 - x1*x1;
	D = num*x1y1 - x1*y1;
	E = num*x3 + num*x1y2 - x1*(x2 + y2);
	G = num*y2 - y1*y1;
	H = num*x2y1 + num*y3 - y1*(x2 + y2);
	a = (H*D - E*G) / (C*G - D*D);
	b = (H*C - E*D) / (D*D - G*C);
	c = -(x2 + y2 + a*x1 + b*y1) / num;
	tempcircle.x = -a / 2; //圆心x坐标
	tempcircle.y = -b / 2;//圆心y坐标
	tempcircle.z = sqrt(a*a + b*b - 4 * c) / 2;//圆心半径
	return tempcircle;
}

最小二乘法拟合椭圆:

 

Point2f LeastSquareFittingEllipse(vector<Point2f> temp_coordinates)//QR分解
{
	float x1 = 0;
	float x2 = 0;
	float x3 = 0;
	float x4 = 0;
	float y1 = 0;
	float y2 = 0;
	float y3 = 0;
	float y4 = 0;
	float x1y1 = 0;
	float x1y2 = 0;
	float x1y3 = 0;
	float x2y1 = 0;
	float x2y2 = 0;
	float x3y1 = 0;
	int num;
	vector<Point2f>::iterator k;
	Point2f tempcircle;
	num = temp_coordinates.size();
	for (k = temp_coordinates.begin(); k != temp_coordinates.end(); k++)
	{
		x1 = x1 + (*k).x;
		x2 = x2 + pow((*k).x, 2);
		x3 = x3 + pow((*k).x, 3);
		x4 = x4 + pow((*k).x, 4);
		y1 = y1 + (*k).y;
		y2 = y2 + pow((*k).y, 2);
		y3 = y3 + pow((*k).y, 3);
		y4 = y4 + pow((*k).y, 4);
		x1y1 = x1y1 + (*k).x * (*k).y;
		x1y2 = x1y2 + (*k).x * pow((*k).y, 2);
		x1y3 = x1y3 + (*k).x * pow((*k).y, 3);
		x2y1 = x2y1 + pow((*k).x, 2) * (*k).y;
		x2y2 = x2y2 + pow((*k).x, 2) * pow((*k).y, 2);
		x3y1 = x3y1 + pow((*k).x, 3) * (*k).y;
	}
	Mat left_matrix = (Mat_<float>(6, 5) << x3y1, x2y2-x4,   x3,    x2y1,  x2,
						x2y2, x1y3-x3y1, x2y1,  x1y2,  x1y1,
						x1y3, y4-x2y2,   x1y2,  y3,    y2,
						x2y1, x1y2-x3,   x2,    x1y1,  x1,
						x1y2, y3-x2y1,   x1y1,  y2,    y1,
						x1y1, y2-x2,     x1,    y1,    num);
	cout << "left_matrix[6,5]=" << left_matrix << endl;
	Mat right_matrix = (Mat_<float>(6, 1) << -x4, -x3y1, -x2y2, -x3, -x2y1, -x2 );
	cout << "right_matrix[6,1]=" << right_matrix << endl;
	Mat ellipse_solution(5, 1, CV_32F);
	double t = getTickCount();
	solve(left_matrix, right_matrix, ellipse_solution, DECOMP_QR);
	t = getTickCount() - t;
	double ConsumeTime = t / (getTickFrequency());
	cout << "time =" << ConsumeTime << endl;
	cout << "ellipse_solution[5,1]=" << ellipse_solution << endl;
	float A, B, C, D, E, F;
	A = 1-ellipse_solution.at<float>(1);
	B = ellipse_solution.at<float>(0);
	C = ellipse_solution.at<float>(1);
	D = ellipse_solution.at<float>(2);
	E = ellipse_solution.at<float>(3);
	F = ellipse_solution.at<float>(4);
	tempcircle.x = (B*E - 2*C*D) / (4*A*C - B*B);
	tempcircle.y = (B*D - 2*A*E) / (4*A*C - B*B);
	return tempcircle;
}
Point2f LeastSquareFittingEllipse_LU(vector<Point2f> temp_coordinates)//LU分解
{
	float x1 = 0;
	float x2 = 0;
	float x3 = 0;
	//float x4 = 0;
	float y1 = 0;
	float y2 = 0;
	float y3 = 0;
	float y4 = 0;
	float x1y1 = 0;
	float x1y2 = 0;
	float x1y3 = 0;
	float x2y1 = 0;
	float x2y2 = 0;
	float x3y1 = 0;
	int num;
	vector<Point2f>::iterator k;
	Point2f tempcircle;
	num = temp_coordinates.size();
	for (k = temp_coordinates.begin(); k != temp_coordinates.end(); k++)
	{
		x1 = x1 + (*k).x;
		x2 = x2 + pow((*k).x, 2);
		x3 = x3 + pow((*k).x, 3);
		//x4 = x4 + pow((*k).x, 4);
		y1 = y1 + (*k).y;
		y2 = y2 + pow((*k).y, 2);
		y3 = y3 + pow((*k).y, 3);
		y4 = y4 + pow((*k).y, 4);
		x1y1 = x1y1 + (*k).x * (*k).y;
		x1y2 = x1y2 + (*k).x * pow((*k).y, 2);
		x1y3 = x1y3 + (*k).x * pow((*k).y, 3);
		x2y1 = x2y1 + pow((*k).x, 2) * (*k).y;
		x2y2 = x2y2 + pow((*k).x, 2) * pow((*k).y, 2);
		x3y1 = x3y1 + pow((*k).x, 3) * (*k).y;
	}
	Mat left_matrix = (Mat_<float>(5, 5) << x2y2, x1y3, x2y1, x1y2, x1y1,
						x1y3, y4, x1y2, y3, y2,
						x2y1, x1y2, x2, x1y1, x1,
						x1y2, y3, x1y1, y2, y1,
						x1y1, y2, x1, y1, num );
	cout << "left_matrix[5,5]=" << left_matrix << endl;
	Mat right_matrix = (Mat_<float>(5, 1) << -x3y1, -x2y2, -x3, -x2y1, -x2);
	cout << "right_matrix[5,1]=" << right_matrix << endl;
	Mat ellipse_solution(5, 1, CV_32F);
	solve(left_matrix, right_matrix, ellipse_solution, DECOMP_LU);
	cout << "ellipse_solution[5,1]=" << ellipse_solution << endl;
	float A, B, C, D, E, F;
	A = ellipse_solution.at<float>(0);
	B = ellipse_solution.at<float>(1);
	C = ellipse_solution.at<float>(2);
	D = ellipse_solution.at<float>(3);
	E = ellipse_solution.at<float>(4);
	tempcircle.x = (2*B*C - A*D) / (A*A - 4*B);
	tempcircle.y = (2*D - A*D) / (A*A - 4*B);
	return tempcircle;
}

 

 

 

 

 

 

 

 

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值