原理
椭圆的一般方程:
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}
θ=21arctanA−CB
椭圆几何中心:
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=4AC−B2BE−2CDYc=4AC−B2BD−2AE
长轴短轴分别为:
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+(A−C)2+B22(AXc2+CYc2+BXcYc−1)b2=A+C−(A−C)2+B22(AXc2+CYc2+BXcYc−1)
离心率:
e
=
c
a
=
a
2
−
b
2
a
e=\frac ca= \frac {\sqrt {a^2-b^2}} a
e=ac=aa2−b2
假设有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;
}