# OpenCV最小二乘法圆拟合

• 做实验要控制变量记录好数据
• 明确主次，条理清晰
• 每天总结一天所为

### 最小二乘法圆拟合

$(x-a)^2+(y-b)^2=r^2$,令：

C++实现如下：

BOOL LeastSquaresCircleFitting(vector<cv::Point2d> &m_Points, cv::Point2d &Centroid, double &dRadius)
{
if (!m_Points.empty())
{
int iNum = (int)m_Points.size();
if (iNum < 3)	return FALSE;
double X1 = 0.0;
double Y1 = 0.0;
double X2 = 0.0;
double Y2 = 0.0;
double X3 = 0.0;
double Y3 = 0.0;
double X1Y1 = 0.0;
double X1Y2 = 0.0;
double X2Y1 = 0.0;
vector<cv::Point2d>::iterator iter;
vector<cv::Point2d>::iterator end = m_Points.end();
for (iter = m_Points.begin(); iter != end; ++iter)
{
X1 = X1 + (*iter).x;
Y1 = Y1 + (*iter).y;
X2 = X2 + (*iter).x * (*iter).x;
Y2 = Y2 + (*iter).y * (*iter).y;
X3 = X3 + (*iter).x * (*iter).x * (*iter).x;
Y3 = Y3 + (*iter).y * (*iter).y * (*iter).y;
X1Y1 = X1Y1 + (*iter).x * (*iter).y;
X1Y2 = X1Y2 + (*iter).x * (*iter).y * (*iter).y;
X2Y1 = X2Y1 + (*iter).x * (*iter).x * (*iter).y;
}
double C = 0.0;
double D = 0.0;
double E = 0.0;
double G = 0.0;
double H = 0.0;
double a = 0.0;
double b = 0.0;
double c = 0.0;
C = iNum * X2 - X1 * X1;
D = iNum * X1Y1 - X1 * Y1;
E = iNum * X3 + iNum * X1Y2 - (X2 + Y2) * X1;
G = iNum * Y2 - Y1 * Y1;
H = iNum * X2Y1 + iNum * Y3 - (X2 + Y2) * Y1;
a = (H * D - E * G) / (C * G - D * D);
b = (H * C - E * D) / (D * D - G * C);
c = -(a * X1 + b * Y1 + X2 + Y2) / iNum;
double A = 0.0;
double B = 0.0;
double R = 0.0;
A = a / (-2);
B = b / (-2);
R = double(sqrt(a * a + b * b - 4 * c) / 2);
Centroid.x = A;
Centroid.y = B;