private List <SpeededUpRobustFeaturePoint> processImage(UnmanagedImage image)
{
// make sure we have grayscale image
UnmanagedImage grayImage = null;
if (image.PixelFormat == PixelFormat.Format8bppIndexed)
{
grayImage = image;
}
else
{
// create temporary grayscale image
grayImage = Grayscale.CommonAlgorithms.BT709.Apply(image);
}
// 1. Compute the integral for the given image
integral = IntegralImage.FromBitmap(grayImage);
// 2. Create and compute interest point response map
if (responses == null)
{
// re-create only if really needed
responses = new ResponseLayerCollection(image.Width, image.Height, octaves, initial);
}
else
{
responses.Update(image.Width, image.Height, initial);
}
// Compute the response map
responses.Compute(integral);
// 3. Suppress non-maximum points
List <SpeededUpRobustFeaturePoint> featureList =
new List <SpeededUpRobustFeaturePoint>();
// for each image pyramid in the response map
foreach (ResponseLayer[] layers in responses)
{
// Grab the three layers forming the pyramid
ResponseLayer bot = layers[0]; // bottom layer
ResponseLayer mid = layers[1]; // middle layer
ResponseLayer top = layers[2]; // top layer
int border = (top.Size + 1) / (2 * top.Step);
int tstep = top.Step;
int mstep = mid.Size - bot.Size;
int r = 1;
// for each row
for (int y = border + 1; y < top.Height - border; y++)
{
// for each pixel
for (int x = border + 1; x < top.Width - border; x++)
{
int mscale = mid.Width / top.Width;
int bscale = bot.Width / top.Width;
double currentValue = mid.Responses[y * mscale, x *mscale];
// for each windows' row
for (int i = -r; (currentValue >= threshold) && (i <= r); i++)
{
// for each windows' pixel
for (int j = -r; j <= r; j++)
{
int yi = y + i;
int xj = x + j;
// for each response layer
if (top.Responses[yi, xj] >= currentValue ||
bot.Responses[yi * bscale, xj *bscale] >= currentValue || ((i != 0 || j != 0) &&
mid.Responses[yi * mscale, xj *mscale] >= currentValue))
{
currentValue = 0;
break;
}
}
}
// check if this point is really interesting
if (currentValue >= threshold)
{
// interpolate to sub-pixel precision
double[] offset = interpolate(y, x, top, mid, bot);
if (System.Math.Abs(offset[0]) < 0.5 &&
System.Math.Abs(offset[1]) < 0.5 &&
System.Math.Abs(offset[2]) < 0.5)
{
featureList.Add(new SpeededUpRobustFeaturePoint(
(x + offset[0]) * tstep,
(y + offset[1]) * tstep,
0.133333333 * (mid.Size + offset[2] * mstep),
mid.Laplacian[y * mscale, x * mscale]));
}
}
}
}
}
descriptor = null;
if (featureType != SpeededUpRobustFeatureDescriptorType.None)
{
descriptor = new SpeededUpRobustFeaturesDescriptor(integral);
descriptor.Extended = featureType == SpeededUpRobustFeatureDescriptorType.Extended;
descriptor.Invariant = computeOrientation;
descriptor.Compute(featureList);
}
else if (computeOrientation)
{
descriptor = new SpeededUpRobustFeaturesDescriptor(integral);
foreach (var p in featureList)
{
p.Orientation = descriptor.GetOrientation(p);
}
}
return(featureList);
}