Пример #1
0
        /// <summary>
        /// Computes a scale-space pyramid from the source image.
        /// </summary>
        /// <param name="source">Source image</param>
        /// <param name="levels">Number of levels per octave</param>
        /// <param name="sigma">Sigma for the initial convolution Gaussian</param>
        /// <returns>A scale-space pyramid</returns>
        public static ScaleSpacePyramid <T> Compute(T source, int levels, float sigma)
        {
            List <T> octaves = new List <T>();
            T        current = Convolution.ConvolveGaussian <T>(source, sigma);

            while (current.Width >= MIN_SIZE && current.Height >= MIN_SIZE)
            {
                octaves.Add(current);
                current = Convolution.ConvolveGaussian <T>(current, 2 * sigma, 2);
            }
            T[,] pyramid = new T[octaves.Count, levels];
            float multiplier = (float)Math.Sqrt(Math.Pow(2, 2.0 / levels) - 1);

            for (int o = 0; o < octaves.Count; o++)
            {
                pyramid[o, 0] = octaves[o];
                float currentSigma = multiplier * sigma;
                for (int l = 1; l < levels; l++)
                {
                    pyramid[o, l] = Convolution.ConvolveGaussian <T>(pyramid[o, l - 1], currentSigma);
                    currentSigma *= multiplier;
                }
            }
            return(new ScaleSpacePyramid <T>(pyramid, sigma));
        }
Пример #2
0
        /// <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);
        }
Пример #3
0
        /// <summary>
        /// Computes a gradient image from the source image.
        /// </summary>
        /// <param name="sigma">The sigma to use when blurring the source image.</param>
        /// <param name="image">Source image</param>
        /// <returns>Gradient image</returns>
        public static unsafe GradientImage Compute(GrayscaleImage image, float sigma)
        {
            int rows    = image.Rows;
            int columns = image.Columns;

            if (sigma > 0)
            {
                image = Convolution.ConvolveGaussian <GrayscaleImage>(image, sigma);
            }
            float[, ,] data = new float[rows, columns, 4];
            fixed(float *src = image.RawArray, dst = data)
            {
                float *srcPtr  = src;
                float *srcPtrP = srcPtr + 1;
                float *dstPtr  = dst;

                dstPtr += 2;
                // X derivative
                for (int r = 0; r < rows; r++)
                {
                    *dstPtr = *srcPtrP - *srcPtr;
                    dstPtr += 4;
                    srcPtrP++;
                    for (int c = 1; c < columns - 1; c++, srcPtr++, srcPtrP++, dstPtr += 4)
                    {
                        *dstPtr = *srcPtrP - *srcPtr;
                    }
                    srcPtrP--;
                    *dstPtr = *srcPtrP - *srcPtr;
                    dstPtr  += 4;
                    srcPtr  += 2;
                    srcPtrP += 2;
                }
                srcPtr  = src;
                srcPtrP = srcPtr + columns;
                dstPtr  = dst;
                dstPtr += 3;
                int stride = 4 * columns;

                for (int c = 0; c < columns; c++, srcPtr++, srcPtrP++, dstPtr += 4)
                {
                    float *srcScan  = srcPtr;
                    float *srcScanP = srcPtrP;
                    float *dstScan  = dstPtr;
                    *      dstScan  = *srcScanP - *srcScan;
                    dstScan  += stride;
                    srcScanP += columns;
                    for (int r = 1; r < rows - 1; r++, dstScan += stride, srcScan += columns, srcScanP += columns)
                    {
                        *dstScan = *srcScanP - *srcScan;
                    }
                    srcScanP -= columns;
                    *dstScan = *srcScanP - *srcScan;
                }
                dstPtr = dst;
                int length = rows * columns;

                for (int i = 0; i < length; i++, dstPtr += 4)
                {
                    setData(dstPtr);
                }
            }

            GradientImage result = new GradientImage();

            result.SetData(data);
            return(result);
        }