Processing math: 100%

{Ck}=argmin(L)L=N1k=0|Pkni=0bi,n(tk)Ci|2

tk=dk/dN1,dk=dk1+|PkPk1|

Bernstein basis polynomial: bi,n(t)=(ni)ti(1t)ni=nj=0tjMji

Mji=n!(nj)!(1)j+ii!(ji)!=(1)j+iMjj(ji)(ji)

note:  Mjj=(nj),Mji=0(j<i)

// calculate binomial coefficients using Pascal's triangle
void binomialCoeffs(int n, double** C) {
    // binomial coefficients
    for (int i = 0; i <= n; i++)
        for (int j = 0; j <= i; j++)
            if (j == 0 || j == i) C[i][j] = 1;
            else                  C[i][j] = C[i - 1][j - 1] + C[i - 1][j];
}
std::vector<double> basisMatrix(int degree) {
    const int n = degree + 1;
    std::vector<double* > C(n);
    std::vector<double> Cbuff(n*n);
    for (int i = n; i-->0;) 
        C[i] = &Cbuff[i * n];
    // C[degree, k]; k=0,..,degree)
    binomialCoeffs(degree, &C[0]);
    // seting the diagonal;
    std::vector<double> M(n * n, 0); // lower triangle; 
    for (int j = 0; j <= degree; j++)
        M[j * n + j] = C[degree][j];
    // compute the remainings;
    for (int i = 0; i <= degree; i++) 
        for (int j = i + 1; j <= degree; j++)
            M[j * n + i] = ((j + i) & 1 ? -1 : 1) * C[j][i] * M[j * n + j];
    return M;
}
728x90

'Computational Geometry' 카테고리의 다른 글

Subdividing a Bezier Curve  (0) 2024.04.18
Derivatives of Bezier Curves  (1) 2024.04.12
Why Cubic Splines?  (9) 2024.03.16
Natural Cubic Spline  (0) 2024.03.11
Approximate Distance Between Ellipse and Point  (0) 2024.03.08
,

주어진 데이터를 잘 피팅하는 직선을 찾기 위해서는 데이터를 이루는 각 점의 y 값과 같은 위치에서 구하려는 직선과의 차이 (residual)의 제곱을 최소화시키는 조건을 사용한다. 그러나 직선의 기울기가 매우 커지는 경우에는  데이터에 들어있는 outlier에 대해서는 그 차이가 매우 커지는 경우가 발생할 수도 있어 올바른 피팅을 방해할 수 있다. 이를 수정하는 간단한 방법 중 하나는 y값의 차이를 이용하지 않고 데이터와 직선 간의 최단거리를 이용하는 것이다. 

수평에서 기울어진 각도가 θ이고 원점에서 거리가 s인 직선의 방정식은 

xsinθycosθ+s=0

이고, 한 점 (xi,yi)에서 이 직선까지 거리는

di=|sinθyicosθxi+s|

이다. 따라서 주어진 데이터에서 떨어진 거리 제곱의 합이 최소인 직선을 구하기 위해서는 다음을 최소화시키는 θ,s을 구해야 한다. L=i(sinθxicosθyi+s)2(θ,s)=argmin(L)

θs에 대한 극값 조건에서 

12Lθ=12sin2θi(x2iy2i)cos2θxiyi+ssinθixi+scosθiyi=0

12Ls=cosθyisinθixiNs=0

주어진 데이터의 질량중심계에서 계산을 수행하면 ixi=iyi=0 이므로 데이터의 2차 모멘트를 A=i(x2iy2i),B=ixiyi로 놓으면 직선의 파라미터를 결정하는 식은

12Asin2θBcos2θ=0tan2θ=2BAs=0

두 번째 식은 직선이 질량중심(질량중심계에서 원점)을 통과함을 의미한다. 첫번째 식을 풀면

tanθ=A±A2+(2B)22B

두 해 중에서 극소값 조건을 만족시키는 해가 직선을 결정한다. 그런데

122Lθ2=Acos2θ+2Bsin2θ=±A2+(2B)2>0

이므로 위쪽 부호로 직선(xsinθ=ycosθ)이 정해진다. 질량중심계에서는 원점을 지나지만 원좌표계로 돌아오면 데이터의 질량중심을 통과하도록 평행이동시키면 된다.

(A+A2+(2B)2)(xˉx)=2B(yˉy)

여기서 주어진 데이터의 질량중심은 원좌표계에서

ˉx=1Nixi,ˉy=1Niyi

이다. 또한 원좌표계에서 AB의 계산은 

A=i[(xiˉx)2(yiˉy)2],B=(xiˉx)(yiˉy)

이 결과는 데이터 분포에 PCA를 적용해서 얻은 결과와 동일하다. PCA에서는 공분산 행렬의 고유값이 큰 쪽에 해당하는 고유벡터가 직선의 방향을 결정했다. https://kipl.tistory.com/211.  또한 통계에서는 Deming regression이라고 불린다.

 

PCA Line Fitting

평면 위에 점집합이 주어지고 이들을 잘 기술하는 직선의 방정식을 구해야 할 경우가 많이 발생한다. 이미지의 에지 정보를 이용해 선분을 찾는 경우에 hough transform과 같은 알고리즘을 이용하는

kipl.tistory.com

728x90

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

Approximate Distance Transform  (0) 2024.06.02
Graph-based Segmentation  (1) 2024.05.26
Cubic Spline Kernel  (1) 2024.03.12
Ellipse Fitting  (0) 2024.03.02
Bilateral Filter  (0) 2024.02.18
,

최소 자승법 문제는 추정치와 실제의 측정치와의 차이를 최소로 만드는 parameter vector를 구하는 것이다.
argminx |A.xb|2.

여기서 design matrix A는 추정에 사용이 된 basis 함수를 각각의 독립변수에서 계산한 값이고, x는 구하고자 하는 parameter vector이며, b는 측정값 vector이다. 예를 들면 주어진 측정값을 n1차의 다항식을 이용하여서 피팅하려고 하는 경우에는 parameter는 다항식의 계수가 되며 n-차원의 vector space을 형성하게 되며, A

Aij=(xi)j,j=0,...,n1

가 일 것이다. 일반적으로 Aijxi에서 계산된 basis-함수의 값이 된다. 위의 식을 x에 대해서 미분을 하면 극값을 취하면 최소자승 문제는 아래의 행렬식을 푸는 문제가 된다

(AT.A).x=AT.b.

AT.An×n matrix다. 이 행렬이 역행렬을 가지게 되면

x=(AT.A)1.(A.b),

를 하여서 원하는 parameter vector를 얻을 수 있다. 그러나 피팅 문제에 따라 행렬 AT.A가 매우 singular 해져 역행렬을 구할 수 없게 되는 경우에 종종 생긴다. 예를 들면, 저주파의 신호를 고주파 기저 함수를 이용하여서 최소자승법을 사용하고자 하는 경우 등에 이러한 문제에 부딪히게 된다. 이런 경우에는 직접적으로 AT.A의 역행렬을 구하는 방법을 이용할 수 없고

A.x=b

의 식을 A의 SVD(Singular Value Decomposition)를 이용하여서 풀 수가 있다. A를 SVD 하면 Am×n=Um×n.wn×n.VTn×n의 형태로 분해할 수 있다. 여기서 w=diag(w0,w1,...nonzero,0,..,0)로 쓰여지는 대각행렬이다. matrix UV의 column vector를 사용하면
A=wk0wkukvTk

의 형태로 쓰인다. ukUk-번째 열벡터이고, vkVk-번째 열벡터로 각각 orthonormal basis를 형성한다. parameter 벡터를 {vk} basis로 전개를 하면 영이 아닌 singularvalue에 해당하는 성분만 가지게 된다. 구체적으로 위의 A 분해와 uTj.uk=δjk, 그리고 kvkvTk=In×n임을 이용하면,

vTk.x=uTk.b/wk,wk0,vTk.x=0,wk=0,  x=wk0(uTk.b/wk)vk,

이어서 위의 해를 구할 수 있다. 이 해는 |A.xb|2를 최소화한다.

cubic polynomial fitting

int svd(double *A, int m, int n, double* w, double *V); // from cmath libary.
void fit_func(double x, double val[], int n) {          // polynomial fitting sample;
    val[0] = 1;
    for(int i = 1; i < n; ++i)
        val[i] = x * val[i - 1];
}
#define EPSILON 1.E-8
int svd_fit(const double x[], const double y[], const int m, const int n,
            void (*fit_func)(double , double [], int ),
            double params[],
            double *error)
{
    double *A = new double [m * n];
    double *w = new double [n];
    double *V = new double [n * n];
    // evaluate design matrix;
    for (int i = 0; i < m; ++i)
        fit_func(x[i], &A[i * n + 0], n) ;

    svd(A, m, n, w, V);
    // now A becomes U matrix;
    // truncate small singular values;
    double wmax = 0;
    for (int i = 0; i < n; ++i)
        if (w[i] > wmax) wmax = w[i];
    double thresh = wmax * EPSILON;
    for (int i = 0; i < n; ++i)
        if (w[i] < thresh) w[i] = 0;
    
    // back substitution;
    double *tmp = new double [n];
    for (int j = 0; j < n; ++j) {
        double s = 0;
        if (w[j]) {
            for (int i = 0; i < m; ++i)
                s += A[i * n + j] * y[i];
            s /= w[j];
        }
        tmp[j] = s;
    }
    for (int j = 0; j < n; ++j) {
        double s = 0;
        for (int jj = 0; jj < n; ++jj)
            s += V[j * n + jj] * tmp[jj];
        params[j] = s;
    };

    //estimate error;
    *error = 0;
    for (int i = 0; i < m; ++i) {
        fit_func(x[i], &A[i * n + 0], n); //use A as a tmp buffer;
        double sum = 0;
        for (int j = 0; j < n; ++j) sum += params[j] * A[i * n + j] ;
        double err = (y[i] - sum);
        *error += err * err ;
    }
    delete[] A; delete[] w; delete[] V;
    delete[] tmp;
    return 1;
}

 

728x90

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

Image rotation by FFT  (0) 2022.02.18
FFT를 이용한 영상의 미분  (0) 2022.02.12
Color Histogram Equalization  (4) 2022.02.07
Least Squares Fitting of Ellipses  (1) 2022.01.27
Circle Fitting: Pratt  (0) 2022.01.20
,