(사진 출처 : http://www.wikihow.com/Calculate-Covariance)
covariance(공분산)의 의미는 x, y 가 존재할때, 이에 대한 상관관계를 의미한다. 예를 들어, x가 커지면 y도 커질까?
covar = dxx dxy
dxy dyy
즉, dx, dy, dxy 3개의 값을 구하면된다.
이제부터,
dxx = sum((x-mean_x)^2)/N
dyy = sum((y-mean_y)^2)/N
dxy = sum((x-mean_x)*(y-mean_y))/N
구할 수 있다.
그런데 더 의미를 찾으면, 우리는 여기에서 dxx, dyy, dxy 어디서 본것 같지 않나요??
즉, edge의 방향 성분과 유사하며, 이는 곧 분포도에 대한 방향을 획득할 수 있다. (참고 - pca의 eigenvector는 이런 축을 나타내는데 이와 연관있다고 할수 있다.)
즉, dxx가 강하면 수평방향, dyy가 강하면 수직방향, dxy가 강하면 대각성 방향성 크다. 다시 말해 그 데이터의 분포도를 대충(?)알 수 있다.
찾아보니 괜찮은 블로그가 있네요. 링크
이 내용에서 보면 데이터의 분포도에 대한 정보에 대한 source가 있습니다.
void DrawProbDistribution (CDC &dc, int offset_x, int offset_y, dMatrix &C)
{
// Draw a probability distribution
// wikipedia에서 Multivariate normal distribution 참조
dMatrix Cinv = !C;
for (double x=-100; x<100; x+=1) {
for (double y=-100; y<100; y+=1) {
/*
dMatrix v(2,1);
v(0,0) = x;
v(1,0) = y;
dMatrix e = ~v*Cinv*v;
double p = exp(-0.5*e(0,0));
*/
// 위 주석 처리한 행렬 연산을 풀어쓰면 다음과 같다.
double p = exp (-0.5*(x*x*Cinv(0,0) + 2*x*y*Cinv(0,1) + y*y*Cinv(1,1)));
dc.SetPixel ((int)(offset_x + x), (int)(offset_y - y), RGB(255*p,0,0));
}
}
}
void DrawCovarianceEllipse_Rotat (CDC &dc, int offset_x, int offset_y, double sigma_xx, double sigma_yy, double sigma_xy)
{
// Draw covariance ellipse
// Derivation from Rotations
// http://www.geom.unimelb.edu.au/nicole/surveynetworks/02a/notes09_01.html 참조
double theta = 0.5*atan(2*sigma_xy/(sigma_yy - sigma_xx));
double st = sin(theta);
double ct = cos(theta);
double a = sqrt(sigma_xx*ct*ct - 2*sigma_xy*st*ct + sigma_yy*st*st);
double b = sqrt(sigma_xx*st*st + 2*sigma_xy*st*ct + sigma_yy*ct*ct);
for (int i=0; i<=360; i+=10) {
double ri = _DEG2RAD*i;
double u = a*cos(ri);
double v = b*sin(ri);
double rx = u*ct + v*st;
double ry = -u*st + v*ct;
if (i==0) dc.MoveTo ((int)(offset_x + rx), (int)(offset_y - ry));
else dc.LineTo ((int)(offset_x + rx), (int)(offset_y - ry));
}
}
void DrawCovarianceEllipse_Eigen (CDC &dc, int offset_x, int offset_y, dMatrix &C)
{
// Draw covariance ellipse
// Derivation from Eigen value and vectors
// Paul Michael Newman의 "C4B | Mobile Robotics"에서 Topic 10.1 Drawing Covariance Ellipses 참조
dVector D;
dMatrix V;
if (C.eigen(D, V)) {
for (unsigned int i = 0; i<D.size(); ++i) {
D[i] = sqrt(D[i]);
}
for (int i=0; i<=360; i+=10) {
double ri = _DEG2RAD*i;
double x = D[0]*cos(ri);
double y = D[1]*sin(ri);
double rx = V(0,0)*x + V(0,1)*y;
double ry = V(1,0)*x + V(1,1)*y;
if (i==0) dc.MoveTo ((int)(offset_x + rx), (int)(offset_y - ry));
else dc.LineTo ((int)(offset_x + rx), (int)(offset_y - ry));
}
}
}
그리고 Covariance를 구한 소스 예는
void cal_ovariance(,,,,,)
{
int sx = roi.x, sy = roi.y;
int ex = roi.x+roi.width, ey = roi.y+roi.height;
if(sx<0) sx = 0; if(sy<0) sy = 0;
if(ey>image->height) ey = image->height;
if(ex>image->width) ex = image->width;
double sumR, sumC, sumRR, sumCC, sumRC, sumW;
sumRR = sumCC = sumR = sumC = sumW = sumRC = 0.0;
GIMAGE _image; // 입력 그레이 이미지
for(int i=sy; i<ey; i++){
for(int j=sx; j<ex; j++){
int val = _image[i][j];
int r = i*val;
int c = j*val;
sumW += val;
sumR += r;
sumC += c;
sumRR += r*i;
sumCC += c*j;
sumRC += val*i*j;
}
}
meanX = sumC/sumW;
meanY = sumR/sumW;
double covRC = (sumRC/sumW)-(meanX*meanY);
// 최종적으로,
dxx = (sumRR/sumW)-powf(meanY,2);
dxy = covRC;
dyy = (sumCC/sumW)-powf(meanX,2);
}
'Research > Math' 카테고리의 다른 글
l0-Norm, l1-Norm, l2-Norm, … , l-infinity Norm (0) | 2014.12.17 |
---|---|
orthogonal matrix = 직교 (0) | 2014.04.25 |