📄 trackfeatures.c
字号:
/*********************************************************************
* trackFeatures.c
*
*********************************************************************/
/* Standard includes */
#include <assert.h>
#include <math.h> /* fabs() */
#include <stdlib.h> /* malloc() */
#include <stdio.h> /* fflush() */
/* Our includes */
#include "base.h"
#include "error.h"
#include "convolve.h" /* for computing pyramid */
#include "klt.h"
#include "klt_util.h" /* _KLT_FloatImage */
#include "pyramid.h" /* _KLT_Pyramid */
extern int KLT_verbose;
typedef float *_FloatWindow;
/*********************************************************************
* _interpolate
*
* Given a point (x,y) in an image, computes the bilinear interpolated
* gray-level value of the point in the image.
*/
static float _interpolate(
float x,
float y,
_KLT_FloatImage img)
{
int xt = (int) x; /* coordinates of top-left corner */
int yt = (int) y;
float ax = x - xt;
float ay = y - yt;
float *ptr = img->data + (img->ncols*yt) + xt;
#ifndef _DNDEBUG
if (xt<0 || yt<0 || xt>=img->ncols-1 || yt>=img->nrows-1) {
fprintf(stderr, "(xt,yt)=(%d,%d) imgsize=(%d,%d)\n"
"(x,y)=(%f,%f) (ax,ay)=(%f,%f)\n",
xt, yt, img->ncols, img->nrows, x, y, ax, ay);
fflush(stderr);
}
#endif
assert (xt >= 0 && yt >= 0 && xt <= img->ncols - 2 && yt <= img->nrows - 2);
return ( (1-ax) * (1-ay) * *ptr +
ax * (1-ay) * *(ptr+1) +
(1-ax) * ay * *(ptr+(img->ncols)) +
ax * ay * *(ptr+(img->ncols)+1) );
}
/*********************************************************************
* _computeIntensityDifference
*
* Given two images and the window center in both images,
* aligns the images wrt the window and computes the difference
* between the two overlaid images.
*/
static void _computeIntensityDifference(
_KLT_FloatImage img1, /* images */
_KLT_FloatImage img2,
float x1, float y1, /* center of window in 1st img */
float x2, float y2, /* center of window in 2nd img */
int width, int height, /* size of window */
_FloatWindow imgdiff) /* output */
{
register int hw = width/2, hh = height/2;
float g1, g2;
register int i, j;
/* Compute values */
for (j = -hh ; j <= hh ; j++)
for (i = -hw ; i <= hw ; i++) {
g1 = _interpolate(x1+i, y1+j, img1);
g2 = _interpolate(x2+i, y2+j, img2);
*imgdiff++ = g1 - g2;
}
}
/*********************************************************************
* _computeGradientSum
*
* Given two gradients and the window center in both images,
* aligns the gradients wrt the window and computes the sum of the two
* overlaid gradients.
*/
static void _computeGradientSum(
_KLT_FloatImage gradx1, /* gradient images */
_KLT_FloatImage grady1,
_KLT_FloatImage gradx2,
_KLT_FloatImage grady2,
float x1, float y1, /* center of window in 1st img */
float x2, float y2, /* center of window in 2nd img */
int width, int height, /* size of window */
_FloatWindow gradx, /* output */
_FloatWindow grady) /* " */
{
register int hw = width/2, hh = height/2;
float g1, g2;
register int i, j;
/* Compute values */
for (j = -hh ; j <= hh ; j++)
for (i = -hw ; i <= hw ; i++) {
g1 = _interpolate(x1+i, y1+j, gradx1);
g2 = _interpolate(x2+i, y2+j, gradx2);
*gradx++ = g1 + g2;
g1 = _interpolate(x1+i, y1+j, grady1);
g2 = _interpolate(x2+i, y2+j, grady2);
*grady++ = g1 + g2;
}
}
/*********************************************************************
* _computeIntensityDifferenceLightingInsensitive
*
* Given two images and the window center in both images,
* aligns the images wrt the window and computes the difference
* between the two overlaid images; normalizes for overall gain and bias.
*/
static void _computeIntensityDifferenceLightingInsensitive(
_KLT_FloatImage img1, /* images */
_KLT_FloatImage img2,
float x1, float y1, /* center of window in 1st img */
float x2, float y2, /* center of window in 2nd img */
int width, int height, /* size of window */
_FloatWindow imgdiff) /* output */
{
register int hw = width/2, hh = height/2;
float g1, g2, sum1_squared = 0, sum2_squared = 0;
register int i, j;
float sum1 = 0, sum2 = 0;
float mean1, mean2,alpha,belta;
/* Compute values */
for (j = -hh ; j <= hh ; j++)
for (i = -hw ; i <= hw ; i++) {
g1 = _interpolate(x1+i, y1+j, img1);
g2 = _interpolate(x2+i, y2+j, img2);
sum1 += g1; sum2 += g2;
sum1_squared += g1*g1;
sum2_squared += g2*g2;
}
mean1=sum1_squared/(width*height);
mean2=sum2_squared/(width*height);
alpha = (float) sqrt(mean1/mean2);
mean1=sum1/(width*height);
mean2=sum2/(width*height);
belta = mean1-alpha*mean2;
for (j = -hh ; j <= hh ; j++)
for (i = -hw ; i <= hw ; i++) {
g1 = _interpolate(x1+i, y1+j, img1);
g2 = _interpolate(x2+i, y2+j, img2);
*imgdiff++ = g1- g2*alpha-belta;
}
}
/*********************************************************************
* _computeGradientSumLightingInsensitive
*
* Given two gradients and the window center in both images,
* aligns the gradients wrt the window and computes the sum of the two
* overlaid gradients; normalizes for overall gain and bias.
*/
static void _computeGradientSumLightingInsensitive(
_KLT_FloatImage gradx1, /* gradient images */
_KLT_FloatImage grady1,
_KLT_FloatImage gradx2,
_KLT_FloatImage grady2,
_KLT_FloatImage img1, /* images */
_KLT_FloatImage img2,
float x1, float y1, /* center of window in 1st img */
float x2, float y2, /* center of window in 2nd img */
int width, int height, /* size of window */
_FloatWindow gradx, /* output */
_FloatWindow grady) /* " */
{
register int hw = width/2, hh = height/2;
float g1, g2, sum1_squared = 0, sum2_squared = 0;
register int i, j;
float sum1 = 0, sum2 = 0;
float mean1, mean2, alpha;
for (j = -hh ; j <= hh ; j++)
for (i = -hw ; i <= hw ; i++) {
g1 = _interpolate(x1+i, y1+j, img1);
g2 = _interpolate(x2+i, y2+j, img2);
sum1_squared += g1; sum2_squared += g2;
}
mean1 = sum1_squared/(width*height);
mean2 = sum2_squared/(width*height);
alpha = (float) sqrt(mean1/mean2);
/* Compute values */
for (j = -hh ; j <= hh ; j++)
for (i = -hw ; i <= hw ; i++) {
g1 = _interpolate(x1+i, y1+j, gradx1);
g2 = _interpolate(x2+i, y2+j, gradx2);
*gradx++ = g1 + g2*alpha;
g1 = _interpolate(x1+i, y1+j, grady1);
g2 = _interpolate(x2+i, y2+j, grady2);
*grady++ = g1+ g2*alpha;
}
}
/*********************************************************************
* _compute2by2GradientMatrix
*
*/
static void _compute2by2GradientMatrix(
_FloatWindow gradx,
_FloatWindow grady,
int width, /* size of window */
int height,
float *gxx, /* return values */
float *gxy,
float *gyy)
{
register float gx, gy;
register int i;
/* Compute values */
*gxx = 0.0; *gxy = 0.0; *gyy = 0.0;
for (i = 0 ; i < width * height ; i++) {
gx = *gradx++;
gy = *grady++;
*gxx += gx*gx;
*gxy += gx*gy;
*gyy += gy*gy;
}
}
/*********************************************************************
* _compute2by1ErrorVector
*
*/
static void _compute2by1ErrorVector(
_FloatWindow imgdiff,
_FloatWindow gradx,
_FloatWindow grady,
int width, /* size of window */
int height,
float step_factor, /* 2.0 comes from equations, 1.0 seems to avoid overshooting */
float *ex, /* return values */
float *ey)
{
register float diff;
register int i;
/* Compute values */
*ex = 0; *ey = 0;
for (i = 0 ; i < width * height ; i++) {
diff = *imgdiff++;
*ex += diff * (*gradx++);
*ey += diff * (*grady++);
}
*ex *= step_factor;
*ey *= step_factor;
}
/*********************************************************************
* _solveEquation
*
* Solves the 2x2 matrix equation
* [gxx gxy] [dx] = [ex]
* [gxy gyy] [dy] = [ey]
* for dx and dy.
*
* Returns KLT_TRACKED on success and KLT_SMALL_DET on failure
*/
static int _solveEquation(
float gxx, float gxy, float gyy,
float ex, float ey,
float small,
float *dx, float *dy)
{
float det = gxx*gyy - gxy*gxy;
if (det < small) return KLT_SMALL_DET;
*dx = (gyy*ex - gxy*ey)/det;
*dy = (gxx*ey - gxy*ex)/det;
return KLT_TRACKED;
}
/*********************************************************************
* _allocateFloatWindow
*/
static _FloatWindow _allocateFloatWindow(
int width,
int height)
{
_FloatWindow fw;
fw = (_FloatWindow) malloc(width*height*sizeof(float));
if (fw == NULL) KLTError("(_allocateFloatWindow) Out of memory.");
return fw;
}
/*********************************************************************
* _printFloatWindow
* (for debugging purposes)
*/
/*
static void _printFloatWindow(
_FloatWindow fw,
int width,
int height)
{
int i, j;
fprintf(stderr, "\n");
for (i = 0 ; i < width ; i++) {
for (j = 0 ; j < height ; j++) {
fprintf(stderr, "%6.1f ", *fw++);
}
fprintf(stderr, "\n");
}
}
*/
/*********************************************************************
* _sumAbsFloatWindow
*/
static float _sumAbsFloatWindow(
_FloatWindow fw,
int width,
int height)
{
float sum = 0.0;
int w;
for ( ; height > 0 ; height--)
for (w=0 ; w < width ; w++)
sum += (float) fabs(*fw++);
return sum;
}
/*********************************************************************
* _trackFeature
*
* Tracks a feature point from one image to the next.
*
* RETURNS
* KLT_SMALL_DET if feature is lost,
* KLT_MAX_ITERATIONS if tracking stopped because iterations timed out,
* KLT_TRACKED otherwise.
*/
static int _trackFeature(
float x1, /* location of window in first image */
float y1,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -