Processing math: 100%

점집합을 일반적인 2차 곡선으로 피팅하는 경우에 방정식은

ax2+by2+cxy+dx+ey+f=0

의 계수를 주어진 데이터를 이용하여서 구해야 한다. 실제 문제에서는 타원, 포물선 쌍곡 선등의 타입에 따라 몇 가지 제약 조건을 넣어 피팅을 한다. 원은 타원의 특별한 경우로 일반적으로 a=b, c=0의 제약 조건이 필요하다. 그러나 보다 엄밀하게 제약을 하게 되면 a=b=1의 추가 조건을 줄 수 있다. 이 경우는 점들이 모두 일직선에 있는 경우를 (a=b=0) 취급할 수 없게 된다. 이 예외적인 경우를 제외하고는 최소자승법을 사용하면 계수를 매우 쉽게 구할 수 있기 때문에 많이 이용된다.

 

문제: 주어진 데이터를 fitting 하는 이차곡선(원)

x2+y2+Ax+By+C=0

의 계수 A,B,C를 최소자승법을 사용해서 구하라. 

 

주어진 점집합이 원 위의 점이면 우변이 0이 되어야 하나, 실제 데이터를 얻는 과정에서 여러 노이즈에 노출되므로 일반적으로 0이 되지 않는다. 최소자승법은 주어진 점들이 원에서 벗어나는 정도의 제곱 합이 최소가 되도록 하는 계수 A,B,C를 결정한다.  원과 점의 편차의 제곱합
L=i|x2i+y2i+Axi+Byi+C|2,

의 극값을 찾기 위해서 A,B, 그리고 C에 대해 미분을 하면

LA=2i(x2i+y2i+Axi+Byi+C)xi=0,

LB=2i(x2i+y2i+Axi+Byi+C)yi=0,

LC=2i(x2i+y2i+Axi+Byi+C)=0.

이 연립방정식을 풀면  A,B,C를 구할 수 있다. 계산을 단순하게 만들고 수치적 안정성을 높이기 위해 입력점들의 질량중심 

mx=1Nixi,my=1Niyi

계에서 계산을 하자. 이를 위해 입력점의 x, y 성분에서 각각 mx, my만큼을 빼준 값을 좌표값으로 대입하면 된다: 

xiximx,yiyimy

그러면 질량중심 좌표계에서는 Sx=ixi=0, Sy=iyi=0이 된다.

우선 세 번째 식에서 

C=Sx2+Sy2N

을 얻을 수 있고, 첫번째와 두 번째 식에서는 각각

Sx2A+SxyB=(Sx3+Sxy2)

SxyA+Sy2B=(Sy3+Sx2y)

을 얻을 수 있다. 이를 풀면

A=Sy2(Sx3+Sxy2)+Sxy(Sy3+Sx2y)Sx2Sy2S2xy

B=Sx2(Sy3+Sx2y)+Sxy(Sx3+Sxy2)Sx2Sy2S2xy

여기서 주어진 데이터의 각 차수에 해당하는 moment는 아래처럼 계산된다:

추정된 원의 중심 (cx,cy)는 

cx=A2,cy=B2

로 주어지고, 반지름은 

r2=c2x+c2yC=c2x+c2y+1N(Sx2+Sy2)

로 주어진다.

Ref: I. Kasa, A curve fitting procedure and its error analysis. IEEE Trans. Inst. Meas., 25:8-14, 1976

/* 구현 코드: 2024.04.01, typing error 수정 & 질량중심계 계산으로 수정;*/
double circleFit_LS(std::vector<CPoint> &Q, double &cx, double &cy, double &radius) {
    if (Q.size() < 3) return -1;
    double sx2 = 0.0, sy2 = 0.0, sxy  = 0.0;
    double sx3 = 0.0, sy3 = 0.0, sx2y = 0.0, sxy2 = 0.0;
    double mx = 0, my = 0;            /* center of mass;*/
    for (int k = Q.size(); k-->0;)
        mx += Q[k].x, my += Q[k].y;
    mx /= Q.size(); my /= Q.size();
    /* compute moments; */
    for (int k = Q.size(); k-->0;) { /* offset (mx, my)*/
        double x = Q[k].x - mx, xx = x * x;
        double y = Q[k].y - my, yy = y * y;
        sx2  += xx;      sy2  += yy;      sxy  += x * y;
        sx3  += x * xx;  sy3  += y * yy;
        sx2y += xx * y;  sxy2 += yy * x;
    }
    double det = sx2 * sy2 - sxy * sxy;
    if (fabs(det) < 1.e-10) return -1;    /*collinear한 경우임;*/
    /* center in cm frame; */
    double a = sx3 + sxy2;
    double b = sy3 + sx2y;
    cx = (sy2 * a - sxy * b) / det / 2;
    cy = (sx2 * b - sxy * a) / det / 2;
    /* radius squared */
    double radsq = cx * cx + cy * cy + (sx2 + sy2) / Q.size();
    radius = sqrt(radsq);
    cx += mx; cy += my; /* recover offset; */
    return fitError(Q, cx, cy, radius);
}

https://kipl.tistory.com/357

 

Circle Fitting: Pratt

주어진 점집합을 원으로 피팅하기 위해 이차식A(x2+y2)+Bx+Cy+D=0을 이용하자. 원의 경우는 A=0인 경우는 직선을 나타내고, A0인 경우가 원을 표현한다. 물론 A=1로 설정을 할 수 있으

kipl.tistory.com

https://kipl.tistory.com/32

 

RANSAC: Circle Fit

RANSAC 알고리즘을 써서 주어진 2차원 점집합에서 원을 추정한다. 원을 만들기 위해서는 최소한 3점이 필요하고, 또 일직선에 있지 않아야 한다. 이렇게 만들어진 원은 세 점을 꼭짓점으로 하는 삼

kipl.tistory.com

 

728x90

'Image Recognition > Fundamental' 카테고리의 다른 글

PCA Line Fitting  (0) 2020.11.12
Histogram Equalization  (0) 2020.11.12
Integer Sqrt  (0) 2020.11.11
Parabolic Interpolation in Peak Finding  (3) 2020.11.10
Histogram Matching  (0) 2012.11.03
,