📄 trackfeatures.c
字号:
T[0][5] += x * gxy;
T[1][1] += xx * gyy;
T[1][2] += xy * gxy;
T[1][3] += xy * gyy;
T[1][4] += x * gxy;
T[1][5] += x * gyy;
T[2][2] += yy * gxx;
T[2][3] += yy * gxy;
T[2][4] += y * gxx;
T[2][5] += y * gxy;
T[3][3] += yy * gyy;
T[3][4] += y * gxy;
T[3][5] += y * gyy;
T[4][4] += gxx;
T[4][5] += gxy;
T[5][5] += gyy;
}
}
for (j = 0 ; j < 5 ; j++) {
for (i = j+1 ; i < 6 ; i++) {
T[i][j] = T[j][i];
}
}
}
/*********************************************************************
* _am_compute6by1ErrorVector
*
*/
static void _am_compute6by1ErrorVector(
_FloatWindow imgdiff,
_FloatWindow gradx,
_FloatWindow grady,
int width, /* size of window */
int height,
float **e) /* return values */
{
register int hw = width/2, hh = height/2;
register int i, j;
register float diff, diffgradx, diffgrady;
/* Set values to zero */
for(i = 0; i < 6; i++) e[i][0] = 0.0;
/* Compute values */
for (j = -hh ; j <= hh ; j++) {
for (i = -hw ; i <= hw ; i++) {
diff = *imgdiff++;
diffgradx = diff * (*gradx++);
diffgrady = diff * (*grady++);
e[0][0] += diffgradx * i;
e[1][0] += diffgrady * i;
e[2][0] += diffgradx * j;
e[3][0] += diffgrady * j;
e[4][0] += diffgradx;
e[5][0] += diffgrady;
}
}
for(i = 0; i < 6; i++) e[i][0] *= 0.5;
}
/*********************************************************************
* _am_compute4by4GradientMatrix
*
*/
static void _am_compute4by4GradientMatrix(
_FloatWindow gradx,
_FloatWindow grady,
int width, /* size of window */
int height,
float **T) /* return values */
{
register int hw = width/2, hh = height/2;
register int i, j;
float gx, gy, x, y;
/* Set values to zero */
for (j = 0 ; j < 4 ; j++) {
for (i = 0 ; i < 4 ; i++) {
T[j][i] = 0.0;
}
}
for (j = -hh ; j <= hh ; j++) {
for (i = -hw ; i <= hw ; i++) {
gx = *gradx++;
gy = *grady++;
x = (float) i;
y = (float) j;
T[0][0] += (x*gx+y*gy) * (x*gx+y*gy);
T[0][1] += (x*gx+y*gy)*(x*gy-y*gx);
T[0][2] += (x*gx+y*gy)*gx;
T[0][3] += (x*gx+y*gy)*gy;
T[1][1] += (x*gy-y*gx) * (x*gy-y*gx);
T[1][2] += (x*gy-y*gx)*gx;
T[1][3] += (x*gy-y*gx)*gy;
T[2][2] += gx*gx;
T[2][3] += gx*gy;
T[3][3] += gy*gy;
}
}
for (j = 0 ; j < 3 ; j++) {
for (i = j+1 ; i < 4 ; i++) {
T[i][j] = T[j][i];
}
}
}
/*********************************************************************
* _am_compute4by1ErrorVector
*
*/
static void _am_compute4by1ErrorVector(
_FloatWindow imgdiff,
_FloatWindow gradx,
_FloatWindow grady,
int width, /* size of window */
int height,
float **e) /* return values */
{
register int hw = width/2, hh = height/2;
register int i, j;
register float diff, diffgradx, diffgrady;
/* Set values to zero */
for(i = 0; i < 4; i++) e[i][0] = 0.0;
/* Compute values */
for (j = -hh ; j <= hh ; j++) {
for (i = -hw ; i <= hw ; i++) {
diff = *imgdiff++;
diffgradx = diff * (*gradx++);
diffgrady = diff * (*grady++);
e[0][0] += diffgradx * i + diffgrady * j;
e[1][0] += diffgrady * i - diffgradx * j;
e[2][0] += diffgradx;
e[3][0] += diffgrady;
}
}
for(i = 0; i < 4; i++) e[i][0] *= 0.5;
}
/*********************************************************************
* _am_trackFeatureAffine
*
* Tracks a feature point from the image of first occurrence to the actual image.
*
* RETURNS
* KLT_SMALL_DET or KLT_LARGE_RESIDUE or KLT_OOB if feature is lost,
* KLT_TRACKED otherwise.
*/
/* if you enalbe the DEBUG_AFFINE_MAPPING make sure you have created a directory "./debug" */
/* #define DEBUG_AFFINE_MAPPING */
#ifdef DEBUG_AFFINE_MAPPING
static int counter = 0;
static int glob_index = 0;
#endif
static int _am_trackFeatureAffine(
float x1, /* location of window in first image */
float y1,
float *x2, /* starting location of search in second image */
float *y2,
_KLT_FloatImage img1,
_KLT_FloatImage gradx1,
_KLT_FloatImage grady1,
_KLT_FloatImage img2,
_KLT_FloatImage gradx2,
_KLT_FloatImage grady2,
int width, /* size of window */
int height,
float step_factor, /* 2.0 comes from equations, 1.0 seems to avoid overshooting */
int max_iterations,
float small, /* determinant threshold for declaring KLT_SMALL_DET */
float th, /* displacement threshold for stopping */
float th_aff,
float max_residue, /* residue threshold for declaring KLT_LARGE_RESIDUE */
int lighting_insensitive, /* whether to normalize for gain and bias */
int affine_map, /* whether to evaluates the consistency of features with affine mapping */
float mdd, /* difference between the displacements */
float *Axx, float *Ayx,
float *Axy, float *Ayy) /* used affine mapping */
{
_FloatWindow imgdiff, gradx, grady;
float gxx, gxy, gyy, ex, ey, dx, dy;
int iteration = 0;
int status = 0;
int hw = width/2;
int hh = height/2;
int nc1 = img1->ncols;
int nr1 = img1->nrows;
int nc2 = img2->ncols;
int nr2 = img2->nrows;
float **a;
float **T;
float one_plus_eps = 1.001f; /* To prevent rounding errors */
float old_x2 = *x2;
float old_y2 = *y2;
KLT_BOOL convergence = FALSE;
#ifdef DEBUG_AFFINE_MAPPING
char fname[80];
_KLT_FloatImage aff_diff_win = _KLTCreateFloatImage(width,height);
printf("starting location x2=%f y2=%f\n", *x2, *y2);
#endif
/* Allocate memory for windows */
imgdiff = _allocateFloatWindow(width, height);
gradx = _allocateFloatWindow(width, height);
grady = _allocateFloatWindow(width, height);
T = _am_matrix(6,6);
a = _am_matrix(6,1);
/* Iteratively update the window position */
do {
if(!affine_map) {
/* pure translation tracker */
/* If out of bounds, exit loop */
if ( x1-hw < 0.0f || nc1-( x1+hw) < one_plus_eps ||
*x2-hw < 0.0f || nc2-(*x2+hw) < one_plus_eps ||
y1-hh < 0.0f || nr1-( y1+hh) < one_plus_eps ||
*y2-hh < 0.0f || nr2-(*y2+hh) < one_plus_eps) {
status = KLT_OOB;
break;
}
/* Compute gradient and difference windows */
if (lighting_insensitive) {
_computeIntensityDifferenceLightingInsensitive(img1, img2, x1, y1, *x2, *y2,
width, height, imgdiff);
_computeGradientSumLightingInsensitive(gradx1, grady1, gradx2, grady2,
img1, img2, x1, y1, *x2, *y2, width, height, gradx, grady);
} else {
_computeIntensityDifference(img1, img2, x1, y1, *x2, *y2,
width, height, imgdiff);
_computeGradientSum(gradx1, grady1, gradx2, grady2,
x1, y1, *x2, *y2, width, height, gradx, grady);
}
#ifdef DEBUG_AFFINE_MAPPING
aff_diff_win->data = imgdiff;
sprintf(fname, "./debug/kltimg_trans_diff_win%03d.%03d.pgm", glob_index, counter);
printf("%s\n", fname);
_KLTWriteAbsFloatImageToPGM(aff_diff_win, fname,256.0);
printf("iter = %d translation tracker res: %f\n", iteration, _sumAbsFloatWindow(imgdiff, width, height)/(width*height));
#endif
/* Use these windows to construct matrices */
_compute2by2GradientMatrix(gradx, grady, width, height,
&gxx, &gxy, &gyy);
_compute2by1ErrorVector(imgdiff, gradx, grady, width, height, step_factor,
&ex, &ey);
/* Using matrices, solve equation for new displacement */
status = _solveEquation(gxx, gxy, gyy, ex, ey, small, &dx, &dy);
convergence = (fabs(dx) < th && fabs(dy) < th);
*x2 += dx;
*y2 += dy;
}else{
/* affine tracker */
float ul_x = *Axx * (-hw) + *Axy * hh + *x2; /* upper left corner */
float ul_y = *Ayx * (-hw) + *Ayy * hh + *y2;
float ll_x = *Axx * (-hw) + *Axy * (-hh) + *x2; /* lower left corner */
float ll_y = *Ayx * (-hw) + *Ayy * (-hh) + *y2;
float ur_x = *Axx * hw + *Axy * hh + *x2; /* upper right corner */
float ur_y = *Ayx * hw + *Ayy * hh + *y2;
float lr_x = *Axx * hw + *Axy * (-hh) + *x2; /* lower right corner */
float lr_y = *Ayx * hw + *Ayy * (-hh) + *y2;
/* If out of bounds, exit loop */
if ( x1-hw < 0.0f || nc1-(x1+hw) < one_plus_eps ||
y1-hh < 0.0f || nr1-(y1+hh) < one_plus_eps ||
ul_x < 0.0f || nc2-(ul_x ) < one_plus_eps ||
ll_x < 0.0f || nc2-(ll_x ) < one_plus_eps ||
ur_x < 0.0f || nc2-(ur_x ) < one_plus_eps ||
lr_x < 0.0f || nc2-(lr_x ) < one_plus_eps ||
ul_y < 0.0f || nr2-(ul_y ) < one_plus_eps ||
ll_y < 0.0f || nr2-(ll_y ) < one_plus_eps ||
ur_y < 0.0f || nr2-(ur_y ) < one_plus_eps ||
lr_y < 0.0f || nr2-(lr_y ) < one_plus_eps) {
status = KLT_OOB;
break;
}
#ifdef DEBUG_AFFINE_MAPPING
counter++;
_am_computeAffineMappedImage(img1, x1, y1, 1.0, 0.0 , 0.0, 1.0, width, height, imgdiff);
aff_diff_win->data = imgdiff;
sprintf(fname, "./debug/kltimg_aff_diff_win%03d.%03d_1.pgm", glob_index, counter);
printf("%s\n", fname);
_KLTWriteAbsFloatImageToPGM(aff_diff_win, fname,256.0);
_am_computeAffineMappedImage(img2, *x2, *y2, *Axx, *Ayx , *Axy, *Ayy, width, height, imgdiff);
aff_diff_win->data = imgdiff;
sprintf(fname, "./debug/kltimg_aff_diff_win%03d.%03d_2.pgm", glob_index, counter);
printf("%s\n", fname);
_KLTWriteAbsFloatImageToPGM(aff_diff_win, fname,256.0);
#endif
_am_computeIntensityDifferenceAffine(img1, img2, x1, y1, *x2, *y2, *Axx, *Ayx , *Axy, *Ayy,
width, height, imgdiff);
#ifdef DEBUG_AFFINE_MAPPING
aff_diff_win->data = imgdiff;
sprintf(fname, "./debug/kltimg_aff_diff_win%03d.%03d_3.pgm", glob_index,counter);
printf("%s\n", fname);
_KLTWriteAbsFloatImageToPGM(aff_diff_win, fname,256.0);
printf("iter = %d affine tracker res: %f\n", iteration, _sumAbsFloatWindow(imgdiff, width, height)/(width*height));
#endif
_am_getGradientWinAffine(gradx2, grady2, *x2, *y2, *Axx, *Ayx , *Axy, *Ayy,
width, height, gradx, grady);
switch(affine_map){
case 1:
_am_compute4by1ErrorVector(imgdiff, gradx, grady, width, height, a);
_am_compute4by4GradientMatrix(gradx, grady, width, height, T);
status = _am_gauss_jordan_elimination(T,4,a,1);
*Axx += a[0][0];
*Ayx += a[1][0];
*Ayy = *Axx;
*Axy = -(*Ayx);
dx = a[2][0];
dy = a[3][0];
break;
case 2:
_am_compute6by1ErrorVector(imgdiff, gradx, grady, width, height, a);
_am_compute6by6GradientMatrix(gradx, grady, width, height, T);
status = _am_gauss_jordan_elimination(T,6,a,1);
*Axx += a[0][0];
*Ayx += a[1][0];
*Axy += a[2][0];
*Ayy += a[3][0];
dx = a[4][0];
dy = a[5][0];
break;
}
*x2 += dx;
*y2 += dy;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -