📄 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() */
/* 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;
}
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;
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_QSORT
static 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
qsort(pointlist, npoints, 3*sizeof(int), _comparePoints);
#else
_quicksort(pointlist, npoints);
#endif
}
/*********************************************************************
* _minEigenvalue
*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -