주어진 점집합을 원으로 피팅하기 위해 이차식
을 이용하자. 원의 경우는
으로 쓸 수 있으므로 좌변이 양수이므로
주어진 각 점들이 정확히 추정하는 원 상에 있지 않으므로 이차식의 좌변의 값이 반드시 0이 되지는 않는다. 잘 피팅하기 위해서는 제한조건을 만족하면 각 점들에서 차이를 최소로 만드는 파라미터를 찾으면 된다:
여기서
로 놓으면 (
로 표현된다. 질량중심 좌표계에서 계산을 하면
인 lagrange multiplier가 고윳값이 되는 일반화된 고윳값 방정식을 얻는다. 이 고윳값 식이 해를 가지려면
이어야 한다. 이 특성 방정식은 4차 다항식이므로 closed form 형태의 해를 쓸 수 있으나 실질적으로 수치해석적으로 구하는 것이 더 편하다(Newton-Raphson).
이므로
그런데 주어진 고윳값
최소의 고윳값에 대해서 고유 방정식을 풀면 고유벡터의 성분은
원의 반지름은
로 주어진다.
** 추가: Sylvester's law of inertia에 의하면 위에서 구하는 고유값
Ref: V. Pratt, Direct least-squares fitting of algebraic surfaces, Computer Graphics 21, 1987, 145–152.

double circleFit(std::vector<CPoint>& data, double& centerx, double& centery, double& radius) {
const int maxIter = 99;
double mx = 0, my = 0;
for (int i = data.size(); i-- > 0;)
mx += data[i].x, my += data[i].y;
// center of mass;
mx /= data.size(); my /= data.size();
// moment calculation;
double Mxy, Mxx, Myy, Mzx, Mzy, Mzz;
Mxx = Myy = Mxy = Mzx = Mzy = Mzz = 0.;
for (int i = data.size(); i-- > 0;) {
double xi = data[i].x - mx; // center of mass coordinate
double yi = data[i].y - my; // center of mass coordinate
double zi = xi * xi + yi * yi;
Mxy += xi * yi; Mxx += xi * xi;
Myy += yi * yi; Mzx += xi * zi;
Mzy += yi * zi; Mzz += zi * zi;
}
Mxx /= data.size(); Myy /= data.size();
Mxy /= data.size(); Mzx /= data.size();
Mzy /= data.size(); Mzz /= data.size();
double Mz = Mxx + Myy;
double Cxy = Mxx * Myy - Mxy * Mxy;
double Vz = Mzz - Mz * Mz;
// coefficients of characteristic polynomial;
double C2 = 4 * Cxy - 3 * Mz * Mz - Mzz;
double C1 = Vz * Mz + 4 * Cxy * Mz - Mzx * Mzx - Mzy * Mzy;
double C0 = Mzx * (Mzx * Myy - Mzy * Mxy) + Mzy * (Mzy * Mxx - Mzx * Mxy) - Vz * Cxy;
// Newton's method starting at lambda = 0
double lambda = 0;
double y = C0; // det(lambda = 0)
for (int iter = 0; iter < maxIter; iter++) {
double Dy = C1 + lambda * (2. * C2 + 16.*lambda * lambda);
double lambdaNew = lambda - y / Dy;
if ((lambdaNew == lambda)) break;
double ynew = C0 + lambdaNew * (C1 + lambdaNew * (C2 + 4 * lambdaNew * lambdaNew));
if (fabs(ynew) >= fabs(y)) break;
lambda = lambdaNew;
y = ynew;
}
double DEL = lambda * lambda - lambda * Mz + Cxy;
double cx = (Mzx * (Myy - lambda) - Mzy * Mxy) / DEL / 2;
double cy = (Mzy * (Mxx - lambda) - Mzx * Mxy) / DEL / 2;
centerx = cx + mx; // recover origianl coordinate;
centery = cy + my;
radius = sqrt(cx * cx + cy * cy + Mz + 2 * lambda);
return fitError(data, centerx, centery, radius);
}
RANSAC: Circle Fit
RANSAC 알고리즘을 써서 주어진 2차원 점집합에서 원을 추정한다. 원을 만들기 위해서는 최소한 3점이 필요하고, 또 일직선에 있지 않아야 한다. 이렇게 만들어진 원은 세 점을 꼭짓점으로 하는
kipl.tistory.com
Least Squares Fitting of Circles
점집합을 일반적인 2차 곡선으로 피팅하는 경우에 방정식은
kipl.tistory.com
'Image Recognition > Fundamental' 카테고리의 다른 글
Color Histogram Equalization (4) | 2022.02.07 |
---|---|
Least Squares Fitting of Ellipses (1) | 2022.01.27 |
Best-fit Ellipse 2 (0) | 2022.01.18 |
Best-fit Ellipse (0) | 2022.01.16 |
Image Moments (0) | 2021.12.04 |