diff --git a/FexTrackerSource/FexImgPyramid.h b/FexTrackerSource/FexImgPyramid.h index e090e0d1c..e9bddec08 100644 --- a/FexTrackerSource/FexImgPyramid.h +++ b/FexTrackerSource/FexImgPyramid.h @@ -18,12 +18,12 @@ public: FexImgPyramidLevel( int sx, int sy ); ~FexImgPyramidLevel(); - int sx, sy; + int sx, sy; // dimensions of this level float CoordMul; - float* Img; - float* GradX; - float* GradY; + float* Img; // actual image data + float* GradX; // X gradients + float* GradY; // Y gradients void Fill( float* Img, float DetectSmoothSigma ); void Scale( FexImgPyramidLevel* old ); diff --git a/FexTrackerSource/FexTracker.cpp b/FexTrackerSource/FexTracker.cpp index 4cf5739d9..551398982 100644 --- a/FexTrackerSource/FexTracker.cpp +++ b/FexTrackerSource/FexTracker.cpp @@ -56,21 +56,29 @@ FexTracker::~FexTracker() void FexTracker::ProcessImage( float *Img, bool bFirst ) { + // Receive new image to track + // This assumes it chronologically directly follows the previously processed image if( bFirst || !CurImg ) { + // First image in series + // Initialise a few things CurFrame = 0; CurImg = new FexImgPyramid( Img, SizX, SizY, Cfg.EdgeDetectSigma, Cfg.DetectSmoothSigma, PyramidSubsampling, PyramidMaxLevels ); nActiveFeatures = 0; int tmp = nFeatures; nFeatures = 0; + // Find initial features FindFeatures( tmp ); } else { + // Check if we've lost too many features, and find some more if that's the case CountActiveFeatures(); if( nActiveFeatures= CurFrame ) nActiveFeatures++; } @@ -103,44 +112,58 @@ FexTrackingFeature* FexTracker::operator [] ( int i ) int FexTracker::GetEigenvalueForPoint( int px, int py ) { + // Determine window in the image to process int sx = px - Cfg.WindowX; int ex = px + Cfg.WindowX; int sy = py - Cfg.WindowY; int ey = py + Cfg.WindowY; + // Clip against the edges of the image if( sx<0 )sx=0; if( sy<0 )sy=0; if( ex>SizX-1 )ex=SizX-1; if( ey>SizY-1 )ey=SizY-1; + // Stride for the image int imgSX = CurImg->lLevels[0]->sx; + // Pointers to X and Y gradient vectors float* gradx = CurImg->lLevels[0]->GradX; float* grady = CurImg->lLevels[0]->GradY; + // Accumulated entries into the correlation matrix [gxx gxy; gxy gyy] register float gxx = 0, gyy = 0, gxy = 0; + // Loop over points inside the window for( int y=sy;y(1<<30) ) val=(1<<30); return (int) val; } +// An int triple (?!) denoting a coordinate pair and an eigenvalue for that position typedef struct{ int val, x, y; }littleFeature; - +// Swap two triples of ints (in reality two littleFeature) #define SWAP3(list, i, j) \ {register int *pi, *pj, tmp; \ pi=list+3*(i); pj=list+3*(j); \ @@ -158,6 +181,7 @@ typedef struct{ *pj=tmp; \ } +// Sort a list of int-triples (littleFeature structs) void _quicksort(int *pointlist, int n) { unsigned int i, j, ln, rn; @@ -198,13 +222,17 @@ void _quicksort(int *pointlist, int n) void FexTracker::FindFeatures( int minFeatures ) { - int nli=0; + // Detect new features, so there's at least minFeatures available + + // First calculate eigenvalues for each pixel in the image... + int nli=0; // Number of LIttle features littleFeature *list = new littleFeature[SizX*SizY]; for( int y=0;y0 ) { list[nli].val = v; @@ -215,26 +243,36 @@ void FexTracker::FindFeatures( int minFeatures ) } } + // ... and sort the list _quicksort( (int*)list, nli ); + // I'll call these "interest points", since they're just candidates for features... int oldN = nFeatures; + // Look through all newly found interest-points and add the most interesting to our + // list of features, until we have at least minFeatures for( int i=0;i= mFeatures ) { + // Allocate new, larger feature list and copy old features into new list mFeatures = nFeatures+9; mFeatures -= mFeatures%8; FexTrackingFeature * nlFeatures = (FexTrackingFeature*) new FexTrackingFeature[mFeatures]; @@ -246,10 +284,12 @@ void FexTracker::FindFeatures( int minFeatures ) for( int cpy2=0;cpy2filename); if (!dest.IsDir()) { destination = subsname.GetPath();