/// <summary> /// Extracts corners from the gradient image. The method used here is one which uses the eigensystem at each /// pixel (computed from the smoothed second moments) to determine whether a corner is present. A corner is /// one in which both eigenvalues are above the threshold. /// </summary> /// <param name="grad">Gradient image of source</param> /// <param name="threshold">Threshold used to determine corners</param> /// <returns>A list of corners</returns> public static unsafe Vector[] Extract(GradientImage grad, float threshold) { EigensystemImage eigen = EigensystemImage.Compute(SecondMomentImage.Compute(grad)); List <Vector> points = new List <Vector>(); int rows = eigen.Rows; int columns = eigen.Columns; fixed(float *src = eigen.RawArray) { float *srcPtr = src; int channels = eigen.Channels; for (int r = 0; r < rows; r++) { for (int c = 0; c < columns; c++, srcPtr += channels) { float lambda1 = srcPtr[0]; float lambda2 = srcPtr[1]; if (lambda1 > threshold && lambda2 > threshold) { points.Add(new DenseVector(new float[] { c, r })); } } } } return(points.ToArray()); }
/// <summary> /// Computes the eigensystem image from the second moment image provided. /// </summary> /// <param name="moments">Contains the second moments used to compute the eigensystem image.</param> /// <param name="sigma">The sigma to use when convolving the second moment image</param> /// <returns>the eigensystem image</returns> public static unsafe EigensystemImage Compute(SecondMomentImage moments, float sigma) { moments = Convolution.ConvolveGaussian <SecondMomentImage>(moments, sigma); int rows = moments.Rows; int columns = moments.Columns; float[, ,] data = new float[rows, columns, 6]; fixed(float *src = moments.RawArray, dst = data) { float *srcPtr = src; float *dstPtr = dst; int length = rows * columns; while (length-- > 0) { float a11 = *srcPtr++; float a22 = *srcPtr++; float a12 = *srcPtr++; float a21 = a12; float sqrt = (float)Math.Sqrt(4 * a12 * a21 + Math.Pow(a11 - a22, 2)); float sum = a11 + a22; float eigen1 = sum + sqrt; float eigen2 = sum - sqrt; float x1, y1; findEigenvector(a11, a12, a21, a22, eigen1, out x1, out y1); float x2, y2; findEigenvector(a11, a12, a21, a22, eigen2, out x2, out y2); *dstPtr++ = eigen1; *dstPtr++ = eigen2; *dstPtr++ = x1; *dstPtr++ = y1; *dstPtr++ = x2; *dstPtr++ = y2; } } EigensystemImage image = new EigensystemImage(); image.SetData(data); return(image); }