📄 selectgoodfeatures.c
字号:
/********************************************************************* * selectGoodFeatures.c * *********************************************************************//* Standard includes */#include <assert.h>#include <stdlib.h> /* malloc(), qsort() */#include <stdio.h> /* fflush() */#include <string.h> /* memset() */#include <math.h> /* fsqrt() */#define fsqrt(X) sqrt(X)/* Our includes */#include "base.h"#include "error.h"#include "convolve.h"#include "klt.h"#include "klt_util.h"#include "pyramid.h"int KLT_verbose = 1;typedef enum {SELECTING_ALL, REPLACING_SOME} selectionMode;/********************************************************************* * _quicksort * Replacement for qsort(). Computing time is decreased by taking * advantage of specific knowledge of our array (that there are * three ints associated with each point). * * This routine generously provided by * Manolis Lourakis <lourakis@csi.forth.gr> * * NOTE: The results of this function may be slightly different from * those of qsort(). This is due to the fact that different sort * algorithms have different behaviours when sorting numbers with the * same value: Some leave them in the same relative positions in the * array, while others change their relative positions. For example, * if you have the array [c d b1 a b2] with b1=b2, it may be sorted as * [a b1 b2 c d] or [a b2 b1 c d]. */#define SWAP3(list, i, j) \{register int *pi, *pj, tmp; \ pi=list+3*(i); pj=list+3*(j); \ \ tmp=*pi; \ *pi++=*pj; \ *pj++=tmp; \ \ tmp=*pi; \ *pi++=*pj; \ *pj++=tmp; \ \ tmp=*pi; \ *pi=*pj; \ *pj=tmp; \}void _quicksort(int *pointlist, int n){ unsigned int i, j, ln, rn; while (n > 1) { SWAP3(pointlist, 0, n/2); for (i = 0, j = n; ; ) { do --j; while (pointlist[3*j+2] < pointlist[2]); do ++i; while (i < j && pointlist[3*i+2] > pointlist[2]); if (i >= j) break; SWAP3(pointlist, i, j); } SWAP3(pointlist, j, 0); ln = j; rn = n - ++j; if (ln < rn) { _quicksort(pointlist, ln); pointlist += 3*j; n = rn; } else { _quicksort(pointlist + 3*j, rn); n = ln; } }}#undef SWAP3/*********************************************************************/static void _fillFeaturemap( int x, int y, uchar *featuremap, int mindist, int ncols, int nrows){ int ix, iy; for (iy = y - mindist ; iy <= y + mindist ; iy++) for (ix = x - mindist ; ix <= x + mindist ; ix++) if (ix >= 0 && ix < ncols && iy >= 0 && iy < nrows) featuremap[iy*ncols+ix] = 1;}/********************************************************************* * _enforceMinimumDistance * * Removes features that are within close proximity to better features. * * INPUTS * featurelist: A list of features. The nFeatures property * is used. * * OUTPUTS * featurelist: Is overwritten. Nearby "redundant" features are removed. * Writes -1's into the remaining elements. * * RETURNS * The number of remaining features. */static void _enforceMinimumDistance( int *pointlist, /* featurepoints */ int npoints, /* number of featurepoints */ KLT_FeatureList featurelist, /* features */ int ncols, int nrows, /* size of images */ int mindist, /* min. dist b/w features */ int min_eigenvalue, /* min. eigenvalue */ KLT_BOOL overwriteAllFeatures){ int indx; /* Index into features */ int x, y, val; /* Location and trackability of pixel under consideration */ uchar *featuremap; /* Boolean array recording proximity of features */ int *ptr; /* Cannot add features with an eigenvalue less than one */ if (min_eigenvalue < 1) min_eigenvalue = 1; /* Allocate memory for feature map and clear it */ featuremap = (uchar *) malloc(ncols * nrows * sizeof(uchar)); memset(featuremap, 0, ncols*nrows); /* Necessary because code below works with (mindist-1) */ mindist--; /* If we are keeping all old good features, then add them to the featuremap */ if (!overwriteAllFeatures) for (indx = 0 ; indx < featurelist->nFeatures ; indx++) if (featurelist->feature[indx]->val >= 0) { x = (int) featurelist->feature[indx]->x; y = (int) featurelist->feature[indx]->y; _fillFeaturemap(x, y, featuremap, mindist, ncols, nrows); } /* For each feature point, in descending order of importance, do ... */ ptr = pointlist; indx = 0; while (1) { /* If we can't add all the points, then fill in the rest of the featurelist with -1's */ if (ptr >= pointlist + 3*npoints) { while (indx < featurelist->nFeatures) { if (overwriteAllFeatures || featurelist->feature[indx]->val < 0) { featurelist->feature[indx]->x = -1; featurelist->feature[indx]->y = -1; featurelist->feature[indx]->val = KLT_NOT_FOUND; featurelist->feature[indx]->aff_img = NULL; featurelist->feature[indx]->aff_img_gradx = NULL; featurelist->feature[indx]->aff_img_grady = NULL; featurelist->feature[indx]->aff_x = -1.0; featurelist->feature[indx]->aff_y = -1.0; featurelist->feature[indx]->aff_Axx = 1.0; featurelist->feature[indx]->aff_Ayx = 0.0; featurelist->feature[indx]->aff_Axy = 0.0; featurelist->feature[indx]->aff_Ayy = 1.0; } indx++; } break; } x = *ptr++; y = *ptr++; val = *ptr++; /* Ensure that feature is in-bounds */ assert(x >= 0); assert(x < ncols); assert(y >= 0); assert(y < nrows); while (!overwriteAllFeatures && indx < featurelist->nFeatures && featurelist->feature[indx]->val >= 0) indx++; if (indx >= featurelist->nFeatures) break; /* If no neighbor has been selected, and if the minimum eigenvalue is large enough, then add feature to the current list */ if (!featuremap[y*ncols+x] && val >= min_eigenvalue) { featurelist->feature[indx]->x = (KLT_locType) x; featurelist->feature[indx]->y = (KLT_locType) y; featurelist->feature[indx]->val = (int) val; featurelist->feature[indx]->aff_img = NULL; featurelist->feature[indx]->aff_img_gradx = NULL; featurelist->feature[indx]->aff_img_grady = NULL; featurelist->feature[indx]->aff_x = -1.0; featurelist->feature[indx]->aff_y = -1.0; featurelist->feature[indx]->aff_Axx = 1.0; featurelist->feature[indx]->aff_Ayx = 0.0; featurelist->feature[indx]->aff_Axy = 0.0; featurelist->feature[indx]->aff_Ayy = 1.0; indx++; /* Fill in surrounding region of feature map, but make sure that pixels are in-bounds */ _fillFeaturemap(x, y, featuremap, mindist, ncols, nrows); } } /* Free feature map */ free(featuremap);}/********************************************************************* * _comparePoints * * Used by qsort (in _KLTSelectGoodFeatures) to determine * which feature is better. * By switching the '>' with the '<', qsort is fooled into sorting * in descending order. */#ifdef KLT_USE_QSORTstatic int _comparePoints(const void *a, const void *b){ int v1 = *(((int *) a) + 2); int v2 = *(((int *) b) + 2); if (v1 > v2) return(-1); else if (v1 < v2) return(1); else return(0);}#endif/********************************************************************* * _sortPointList */static void _sortPointList( int *pointlist, int npoints){#ifdef KLT_USE_QSORT
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -