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

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

xsinθycosθ+s=0xsinθycosθ+s=0

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

di=|sinθyicosθxi+s|di=|sinθyicosθxi+s|

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

θθss에 대한 극값 조건에서 

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

12Ls=cosθyisinθixiNs=012Ls=cosθyisinθixiNs=0

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

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

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

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

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

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

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

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

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

ˉx=1Nixi,ˉy=1Niyi¯x=1Nixi,¯y=1Niyi

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

A=i[(xiˉx)2(yiˉy)2],B=(xiˉx)(yiˉy)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
,

일반적인 conic section 피팅은 주어진 데이터 {(xi,yi)}{(xi,yi)}를 가장 잘 기술하는 이차식

F(x,y)=ax2+bxy+cy2+dx+ey+f=0F(x,y)=ax2+bxy+cy2+dx+ey+f=0

의 계수 uT=(a,b,c,d,e,f)uT=(a,b,c,d,e,f)을 찾는 문제이다. 이 conic section이 타원이기 위해서는 2차항의 계수 사이에 다음과 같은 조건을 만족해야 한다.

ellipse constraint:  acb2/4>0ellipse constraint:  acb2/4>0

그리고 얼마나 잘 피팅되었난가에 척도가 필요한데 여기서는 주어진 데이터의 대수적 거리 F(x,y)F(x,y)을 이용하자. 주어진 점이 타원 위의 점이면 이 값은 정확히 0이 된다. 물론 주어진 점에서 타원까지의 거리를 사용할 수도 있으나 이는 훨씬 복잡한 문제가 된다.  따라서 해결해야 하는 문제는

L=i(ax2i+bxiyi+cy2i+dxi+eyi+f)2λ(4acb21)=|(x20x0y0y20x0y01x21x1y1y21x1y11x22x2y2y22x2y21)(abcdef)|2λ(uT(002000010000200000000000000000000000)u1)=uTDTDuλ(uTCu1)=uTSuλ(uTCu1)

을 최소화시키는 계수 벡터 u를 찾는 것이다. 여기서 제한조건으로 4acb2=1=uTCu로 설정했다. 

uT에 대해서 미분을 하면 

LuT=SuλCu=0

즉, 주어진 제한조건 4acb2=1하에서 대수적 거리를 최소화시키는 타원방정식의 계수 u를 구하는 문제는 scattering matrix S=DTD에 대한 일반화된 고유값 문제로 환원이 된다.

Su=λCuuTCu=1

이 문제의 풀이는 직전의 포스팅에서 다른 바 있는데 S의 제곱근 행렬 Q=S1/2를 이용하면 된다. 주어진 고유값 λ와 고유벡터 u가 구해지면 대수적 거리는 uTSu=λ

이므로 이를 최소화시키기 위해서는 양의 값을 갖는 고유값 중에 최소에 해당하는 고유벡터를 고르면 된다. 그런데 고유값 λ의 부호별 개수는 C의 고유값 부호별 개수와 동일함을 보일 수 있는데 (Sylverster's law of inertia),  C의 고유값이 {2,1,2,0,0,0}이므로 λ>0인 고유값은 1개 뿐임을 알 수 있다. 따라서 Su=λCu를 풀어서 얻은  유일한 양의 고유값에 해당하는 고유벡터가 원하는 답이 된다.

https://kipl.tistory.com/370

 

Least Squares Fitting of Ellipses

일반적인 이차곡선은 다음의 이차식으로 표현이 된다: F(x,y)=ax2+bxy+cy2+dx+ey+f=0 6개의 계수는 모두 독립적이지 않고 어떤 종류의 이차곡선인가에 따라 제약조건이 들어온다. 주어진

kipl.tistory.com

https://kipl.tistory.com/565

 

Generalized eigenvalues problem

S가 positive definite 행렬이고, C는 대칭행렬일 때 아래의 일반화된 eigenvalue 문제를 푸는 방법을 알아보자. Su=λCu 타원을 피팅하는 문제에서 이런 형식의 고유값 문제에 부딛

kipl.tistory.com

 Ref: https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/ellipse-pami.pdf

 

 
double FitEllipse(std::vector<CPoint>& points, double einfo[6] ) {     
    if ( points.size() < 6 ) return -1;
    double eigvals[6];
    std::vector<double> D(6 * points.size());
    double S[36];/*  S = ~D * D  */
    double C[36];
    double EIGV[36];/* R^T; transposed orthogonal matrix;*/

    double offx = 0, offy = 0;
    /* shift all points to zero */
    for(int i = points.size(); i--> 0; ) {	
        offx += points[i].x;
        offy += points[i].y;        	
    }
    offx /= points.size(); 
    offy /= points.size();

    /* for the sake of numerical stability, scale down to [-1:1];*/
    double smax = points[0].x, smin = points[0].y;
    for (int i = points.size(); i-->1; ) {
        smax = max(smax, max(points[i].x, points[i].y));
        smin = min(smin, min(points[i].x, points[i].y));
    }
    double scale = smax - smin; 
    double invscale = 1 / scale;
    /* ax^2 + bxy + cy^2 + dx + ey + f = 0*/
    /* fill D matrix rows as (x*x, x*y, y*y, x, y, 1 ) */
    for(int i = points.size(); i--> 0; ) {	
        double x = points[i].x - offx; x *= invscale; 
        double y = points[i].y - offy; y *= invscale;
        D[i*6 + 0] = x*x; D[i*6 + 1] = x*y;
        D[i*6 + 2] = y*y; D[i*6 + 3] = x;
        D[i*6 + 4] = y;   D[i*6 + 5] = 1;		
    }			

    /* scattering matrix: S = ~D * D (6x6)*/
    for (int i = 0; i < 6; i++) 
        for (int j = i; j < 6; j++) { /*upper triangle;*/
            double s = 0;
            for (int k = points.size(); k-- > 0; ) 
                s += D[k*6 + i] * D[k*6 + j];
            S[i*6 + j] = s;
        }
    for (int i = 1; i < 6; i++) /*lower triangle;*/
        for (int j = 0; j < i; j++) 	
            S[i*6 + j] = S[j*6 + i] ;
    
    /* fill constraint matrix C */
    for (int i = 0; i < 36 ; i++ ) C[i] = 0;
    C[12] =  2 ;//2x0 
    C[2 ] =  2 ;//0x2 
    C[7 ] = -1 ;//1x1

    /* find eigenvalues/vectors of scattering matrix; */
    double RT[36];	/* each row contains eigenvector; */
    JacobiEigens ( S, RT, eigvals, 6, 0 );
    /* create R and INVQ;*/
    double R[36];
    for (int i = 0; i < 6 ; i++) {
        eigvals[i] = sqrt(eigvals[i]);
        for ( int k = 0; k < 6; k++ ) {
            R[k*6 + i] = RT[i*6 + k];  /* R = orthogonal mat = transpose(RT);*/
            RT[i*6 + k] /= eigvals[i]; /* RT /= sqrt(eigenvalue) row-wise)*/
        }
    }
    /* create INVQ=R*(1/sqrt(eigenval))*RT;*/
    double INVQ[36];
    _MatrixMul(R, RT, 6, INVQ);

    /* create matrix INVQ*C*INVQ */
    double TMP1[36], TMP2[36];
    _MatrixMul(INVQ, C, 6, TMP1 );
    _MatrixMul(TMP1, INVQ, 6, TMP2 );
    
    /* find eigenvalues and vectors of INVQ*C*INVQ:*/
    JacobiEigens ( TMP2, EIGV, eigvals, 6, 0 );
    /* eigvals stores eigenvalues in descending order of abs(eigvals);*/
    /* search for a unique positive eigenvalue;*/
    int index = -1, count = 0;
    for (int i = 0 ; i < 3; i++ ) {
        if (eigvals[i] > 0) {
            index = i; // break;
            count++;
        }
    }
    /* only 3 eigenvalues must be non-zero 
    ** and only one of them must be positive;*/
    if ((count != 1) || (index == -1)) 
        return -1;
     
    /* eigenvector what we want: u = INVQ * v */
    double u[6]; 
    double *vec = &EIGV[index*6];
    for (int i = 0; i < 6 ; i++) {
        double s = 0;
        for (int k = 0; k < 6; k++) s += INVQ[i*6 + k] * vec[k];
        u[i] = s;
    }
    /* extract shape infos;*/
    PoseEllipse(u, einfo);
    /* recover original scale; center(0,1) and radii(2,3)*/
    for (int i = 0; i < 4; i++) einfo[i] *= scale;
    /* recover center */
    einfo[0] += offx; 
    einfo[1] += offy;
    return FitError(points, offx, offy, scale, u);
};
728x90

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

Linear Least Square Fitting: perpendicular offsets  (0) 2024.03.22
Cubic Spline Kernel  (1) 2024.03.12
Bilateral Filter  (0) 2024.02.18
파라미터 공간에서 본 최소자승 Fitting  (0) 2023.05.21
영상에 Impulse Noise 넣기  (2) 2023.02.09
,

S가 positive definite 행렬이고, C는 대칭행렬일 때 아래의 일반화된 eigenvalue 문제를 푸는 방법을 알아보자. 
Su=λCu

타원을 피팅하는 문제에서 이런 형식의 고유값 문제에 부딛히게 된다. 이 경우 S는 scattering matrix이고, C는 타원피팅에 걸리는 제한조건때문에 나온다. S가 positive definite이므로  S의 eigenvalues {σi>0}는 모두 0보다 크고, eigenvector를 이용하면 

S=RΛRT,    Λ=diag(σ1,...,σn)

처럼 분해할 수 있다. RS의 eigenvector를 열로 가지는 행렬로 orthogonal 행렬이다: R1=RT.

 

이제 S의 제곱근 행렬을 Q, Q2=S라면 

Q=RΛ1/2RT,    Λ1/2=diag(σ1,...,σn)

임을 쉽게 확인할 수 있다. Q을 이용하면 구하려는 고유값 문제는 

QQu=λCu  Qu=λQ1CQ1Qu    v=λQ1CQ1v

이므로 Q1CQ1의 고유값 문제 (1/λ,Qu)로 단순화됨을 알 수 있다. Q의 역행렬이 Q1=RΛ1/2RT임을 쉽게 체크할 수 있으므로 직접적으로 역행렬을 계산할 필요가 없어진다.

Λ1/2=diag(1/σ1,...,1/σn)

728x90

'Mathematics' 카테고리의 다른 글

The Double Bubble Theorem  (0) 2024.05.27
Fourier Interpolation  (0) 2024.03.20
수치적으로 보다 정밀한 이차방정식의 해  (0) 2024.02.23
열방정식의 Green function  (0) 2024.02.12
지구의 나이는(Age of Earth)?  (0) 2024.02.11
,