/// <summary> /// Releases unmanaged and - optionally - managed resources. /// </summary> /// /// <param name="disposing"><c>true</c> to release both managed and unmanaged /// resources; <c>false</c> to release only unmanaged resources.</param> /// protected virtual void Dispose(bool disposing) { if (disposing) { // free managed resources } this.responses = null; this.integral = null; this.descriptor = null; }
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); }