// Incrementally blur the input image first so it reaches the next octave. public void BuildGaussianMaps(ImageMap first, double firstScale, int scales, double sigma) { // We need one more gaussian blurred image than the number of DoG // maps. But for the minima/maxima pixel search, we need two more. See // BuildDiffMaps. imgScaled = new ImageMap[scales + 1 + 1 + 1]; this.basePixScale = firstScale; // Convolve first image with the octaveSigma. Previously we got this // wrong, but thanks to Alexandre Jenny, this got fixed. Thanks! GaussianConvolution gauss = new GaussianConvolution(sigma); ImageMap prev = imgScaled[0] = gauss.Convolve(first); // Ln1(x, y, k^{p+1}) = G(x, y, k) * Ln0(x, y, k^p). for (int scI = 1; scI < imgScaled.Length; ++scI) { gauss = new GaussianConvolution(sigma); // TODO: real fix, "first" is the correct behaviour, however, a // large sigma leads to a large convolution kernel -> slow // better: incremental convolution with smaller sigma. prev = imgScaled[scI] = gauss.Convolve(first); sigma *= SToK(scales); } }
public void BuildGaussianMaps(ImageMap first, double firstScale, int scales, double sigma) { imgScaled = new ImageMap[scales + 1 + 1 + 1]; this.basePixScale = firstScale; ImageMap prev = first; imgScaled[0] = first; double w = sigma; double kTerm = Math.Sqrt(Math.Pow(SToK(scales), 2.0) - 1.0); for (int scI = 1; scI < imgScaled.Length; ++scI) { GaussianConvolution gauss = new GaussianConvolution(w * kTerm); prev = imgScaled[scI] = gauss.Convolve(prev); w *= SToK(scales); } #if false for (int scI = 0; scI < imgScaled.Length; ++scI) { imgScaled[scI].Save("scale-" + scI + ".dat", null); if (scI < (imgScaled.Length - 1)) { (imgScaled[scI + 1] - imgScaled[scI]).Save ("scale-diff-" + scI + ".dat", null); } } Console.WriteLine("DEBUG EXIT"); #endif }
//OK, 04/13/2009 public void ConstructScaleSpace() { Matrix tempMatrix = IRI.Ket.DigitalImageProcessing.GeometricEnhancement.DoubleTheSize(this.originalImage); tempMatrix = new GaussianConvolution(1.5).Convolve(tempMatrix); originalStandardDeviation *= 0.5; for (int n = 0; n < depthOfScale; n++) { //We need s + 3 images in each octave. [David Lowe 2004] for (int s = 0; s < depthOfBlure + 3; s++) { if (s == 0) { //if (n != 0) //{ scaleSpace.Add(tempMatrix); //} continue; } double standarDeviation = CalculateSigma(n, s); scaleSpace.Add(new GaussianConvolution(standarDeviation).Convolve(tempMatrix)); } // index of image in the current octave (has the twice // scale of first image in the current octave) to be // half, int tempIndex = n * (this.depthOfBlure + 3) + depthOfBlure; tempMatrix = IRI.Ket.DigitalImageProcessing.GeometricEnhancement.HalveTheSize(scaleSpace[tempIndex]); } }
public int DetectFeaturesDownscaled(ImageMap img, int bothDimHi, double startScale) { globalKeypoints = globalNaturalKeypoints = null; if (printWarning) { Console.Error.WriteLine(""); Console.Error.WriteLine("==============================================================================="); Console.Error.WriteLine("The use of this software is restricted by certain conditions."); Console.Error.WriteLine("See the \"LICENSE\" file distributed with the program for details."); Console.Error.WriteLine(""); Console.Error.WriteLine("The University of British Columbia has applied for a patent on the SIFT"); Console.Error.WriteLine("algorithm in the United States. Commercial applications of this software may"); Console.Error.WriteLine("require a license from the University of British Columbia."); Console.Error.WriteLine("==============================================================================="); Console.Error.WriteLine(""); } if (bothDimHi < 0) { img = img.ScaleDouble(); startScale *= 0.5; } else if (bothDimHi > 0) { while (img.XDim > bothDimHi || img.YDim > bothDimHi) { img = img.ScaleHalf(); //pass startScale *= 2.0; } } if (preprocSigma > 0.0) { GaussianConvolution gaussianPre = new GaussianConvolution(preprocSigma); img = gaussianPre.Convolve(img); } pyr = new OctavePyramid(); pyr.Verbose = verbose; pyr.BuildOctaves(img, startScale, scaleSpaceLevels, octaveSigma, minimumRequiredPixelsize); globalKeypoints = new ArrayList(); for (int on = 0; on < pyr.Count; ++on) { DScaleSpace dsp = pyr[on]; ArrayList peaks = dsp.FindPeaks(dogThresh); if (verbose) { Console.WriteLine("Octave {0} has {1} raw peaks", on, peaks.Count); } int oldCount = peaks.Count; ArrayList peaksFilt = dsp.FilterAndLocalizePeaks(peaks, maximumEdgeRatio, dValueLowThresh, scaleAdjustThresh, relocationMaximum); if (verbose) { Console.WriteLine(" filtered: {0} remaining from {1}, thats % {2:N2}", peaksFilt.Count, oldCount, (100.0 * peaksFilt.Count) / oldCount); Console.WriteLine("generating keypoints from peaks"); } dsp.GenerateMagnitudeAndDirectionMaps(); ArrayList keypoints = dsp.GenerateKeypoints(peaksFilt, scaleSpaceLevels, octaveSigma); dsp.ClearMagnitudeAndDirectionMaps(); globalKeypoints.AddRange(keypoints); } return(globalKeypoints.Count); }