二维点拟合椭圆

原理

椭圆的一般方程:
A x 2 + B x y + C y 2 + D x + E y + 1 = 0 Ax^2+Bxy+Cy^2+Dx+Ey+1=0 Ax2+Bxy+Cy2+Dx+Ey+1=0
长轴倾角:
θ = 1 2 a r c t a n B A − C \theta=\frac12arctan \frac B{A-C} θ=21arctanACB
椭圆几何中心:
X c = B E − 2 C D 4 A C − B 2 Y c = B D − 2 A E 4 A C − B 2 X_c=\frac {BE-2CD}{4AC-B^2}\\ \\Y_c=\frac {BD-2AE}{4AC-B^2} Xc=4ACB2BE2CDYc=4ACB2BD2AE
长轴短轴分别为:
a 2 = 2 ( A X c 2 + C Y c 2 + B X c Y c − 1 ) A + C + ( A − C ) 2 + B 2 b 2 = 2 ( A X c 2 + C Y c 2 + B X c Y c − 1 ) A + C − ( A − C ) 2 + B 2 a^2=\frac {2(AX_c^2+CY_c^2+BX_cY_c-1)}{A+C+\sqrt {(A-C)^2+B^2}}\\ b^2=\frac {2(AX_c^2+CY_c^2+BX_cY_c-1)}{A+C-\sqrt {(A-C)^2+B^2}} a2=A+C+(AC)2+B2 2(AXc2+CYc2+BXcYc1)b2=A+C(AC)2+B2 2(AXc2+CYc2+BXcYc1)
离心率:
e = c a = a 2 − b 2 a e=\frac ca= \frac {\sqrt {a^2-b^2}} a e=ac=aa2b2

假设有n个椭圆上的点需要拟合:
( x i , y i ) , i = 1 , 2 , . . . , n (x_i,y_i),i=1,2,...,n (xi,yi),i=1,2,...,n

则:
[ x i 2 x i y i y i 2 x y ] [ A B C D E ] = − 1 \begin{bmatrix} x_i^2 & x_iy_i & y_i^2 & x &y\end{bmatrix} \begin{bmatrix} A\\ B \\ C\\D\\E\end{bmatrix}= -1 [xi2xiyiyi2xy]ABCDE=1

代码

//椭圆的中心坐标
cv::Point2f measure::EllipticCentrePoint(std::vector<cv::Point2f> &points, cv::Point2f &CentrePoints)
{
	//float A, B, C, D, E;
	cv::Mat InputArray1 = cv::Mat(points.size(), 5, CV_32F, cv::Scalar(0));
	cv::Mat OutputArray;

	for (int i = 0; i < points.size(); i++)
	{
		//Ax^2+Bxy+Cy^2+Dx+Ey+1=0椭圆方程
		InputArray1.at<float>(i, 0) = float(pow(points[i].x, 2));//x^2
		InputArray1.at<float>(i, 1) = points[i].x *points[i].y;//xy
		InputArray1.at<float>(i, 2) = pow(points[i].y, 2);//y^2
		InputArray1.at<float>(i, 3) = points[i].x;//x
		InputArray1.at<float>(i, 4) = points[i].y;//y
		//InputArray1.at<float>(i, 4) = 1;//1
	}
	cv::Mat InputArray2 = cv::Mat(points.size(), 1, CV_32F, cv::Scalar(-1));
	cv::solve(InputArray1, InputArray2, OutputArray, CV_SVD);
	float A = OutputArray.at<float>(0, 0);
	float B = OutputArray.at<float>(1, 0);
	float C = OutputArray.at<float>(2, 0);
	float D = OutputArray.at<float>(3, 0);
	float E = OutputArray.at<float>(4, 0);
	float EllipseCenterX = float(B * E - 2 * C * D) / (4 * A * C - B * B);
	float EllipseCenterY = float(B * D - 2 * A * E) / (4 * A * C - B * B);
	CentrePoints.x = EllipseCenterX;
	CentrePoints.y = EllipseCenterY;
	return CentrePoints;
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值