private static int[] maximum(IntPoint[] corners, int[] scores)
{
int n = corners.Length;
List<int> maximum = new List<int>(n);
if (corners.Length == 0)
return maximum.ToArray();
int last_row;
int[] row_start;
// Point above points (roughly) to the pixel above
// the one of interest, if there is a feature there.
int point_above = 0;
int point_below = 0;
// Find where each row begins (the corners are output in raster scan order).
// A beginning of -1 signifies that there are no corners on that row.
last_row = corners[n - 1].Y;
row_start = new int[last_row + 1];
for (int i = 0; i < last_row + 1; i++)
row_start[i] = -1;
int prev_row = -1;
for (int i = 0; i < n; i++)
{
if (corners[i].Y != prev_row)
{
row_start[corners[i].Y] = i;
prev_row = corners[i].Y;
}
}
// for each detected corner
for (int i = 0; i < n; i++)
{
int score = scores[i];
IntPoint pos = corners[i];
// Check left
if (i > 0)
if (corners[i - 1].X == pos.X - 1 &&
corners[i - 1].Y == pos.Y && scores[i - 1] >= score)
continue;
// Check right
if (i < (n - 1))
if (corners[i + 1].X == pos.X + 1 &&
corners[i + 1].Y == pos.Y && scores[i + 1] >= score)
continue;
// Check above (if there is a valid row above)
if (pos.Y != 0 && row_start[pos.Y - 1] != -1)
{
// Make sure that current point_above is one row above.
if (corners[point_above].Y < pos.Y - 1)
point_above = row_start[pos.Y - 1];
// Make point_above point to the first of the pixels above the current point, if it exists.*/
for (; corners[point_above].Y < pos.Y && corners[point_above].X < pos.X - 1; point_above++) ;
for (int j = point_above; corners[j].Y < pos.Y && corners[j].X <= pos.X + 1; j++)
{
int x = corners[j].X;
if ((x == pos.X - 1 || x == pos.X || x == pos.X + 1) && scores[j] >= score)
goto next_corner;
}
}
// Check below (if there is anything below)
if (pos.Y != last_row && row_start[pos.Y + 1] != -1 && point_below < n)
{
// Nothing below
if (corners[point_below].Y < pos.Y + 1)
point_below = row_start[pos.Y + 1];
// Make point below point to one of the pixels below the current point, if it exists.
for (; point_below < n && corners[point_below].Y == pos.Y + 1 && corners[point_below].X < pos.X - 1; point_below++) ;
for (int j = point_below; j < n && corners[j].Y == pos.Y + 1 && corners[j].X <= pos.X + 1; j++)
{
int x = corners[j].X;
if ((x == pos.X - 1 || x == pos.X || x == pos.X + 1) && scores[j] >= score)
goto next_corner;
}
}
// The current point is a local maximum.
// Add its index to the list of indices.
maximum.Add(i);
next_corner:
continue;
}
return maximum.ToArray();
}