コード例 #1
0
            /// <summary>
            ///   Returns an enumerator that iterates through the collection.
            /// </summary>
            ///
            /// <returns>
            ///   A <see cref="T:System.Collections.Generic.IEnumerator`1"/> that can be used to iterate through the collection.
            /// </returns>
            ///
            public IEnumerator <ResponseLayer[]> GetEnumerator()
            {
                ResponseLayer[] pyramid = new ResponseLayer[3];

                for (int i = 0; i < octaves; i++)
                {
                    // for each set of response layers
                    for (int j = 0; j <= 1; j++)
                    {
                        // Grab the three layers forming the pyramid
                        pyramid[0] = responses[map[i, j + 0]];
                        pyramid[1] = responses[map[i, j + 1]];
                        pyramid[2] = responses[map[i, j + 2]];
                        yield return(pyramid);
                    }
                }
            }
コード例 #2
0
        private static double[] interpolate(int y, int x, ResponseLayer top, ResponseLayer mid, ResponseLayer bot)
        {
            int bs = bot.Width / top.Width;
            int ms = mid.Width / top.Width;
            int xp1 = x + 1, yp1 = y + 1;
            int xm1 = x - 1, ym1 = y - 1;

            // Compute first order scale-space derivatives
            double dx = (mid.Responses[y * ms, xp1 *ms] - mid.Responses[y * ms, xm1 *ms]) / 2f;
            double dy = (mid.Responses[yp1 * ms, x *ms] - mid.Responses[ym1 * ms, x *ms]) / 2f;
            double ds = (top.Responses[y, x] - bot.Responses[y * bs, x *bs]) / 2f;

            double[] d =
            {
                -dx,
                -dy,
                -ds
            };

            // Compute Hessian
            double v   = mid.Responses[y * ms, x *ms] * 2.0;
            double dxx = (mid.Responses[y * ms, xp1 *ms] + mid.Responses[y * ms, xm1 *ms] - v);
            double dyy = (mid.Responses[yp1 * ms, x *ms] + mid.Responses[ym1 * ms, x *ms] - v);
            double dxs = (top.Responses[y, xp1] - top.Responses[y, x - 1] - bot.Responses[y * bs, xp1 *bs] + bot.Responses[y * bs, xm1 *bs]) / 4f;
            double dys = (top.Responses[yp1, x] - top.Responses[y - 1, x] - bot.Responses[yp1 * bs, x *bs] + bot.Responses[ym1 * bs, x *bs]) / 4f;
            double dss = (top.Responses[y, x] + bot.Responses[y * ms, x *ms] - v);
            double dxy = (mid.Responses[yp1 * ms, xp1 *ms] - mid.Responses[yp1 * ms, xm1 *ms]
                          - mid.Responses[ym1 * ms, xp1 *ms] + mid.Responses[ym1 * ms, xm1 *ms]) / 4f;

            double[,] H =
            {
                { dxx, dxy, dxs },
                { dxy, dyy, dys },
                { dxs, dys, dss },
            };

            // Compute interpolation offsets
            return(H.Inverse(true).Multiply(d));
        }
コード例 #3
0
        /// <summary>
        ///   Process image looking for interest points.
        /// </summary>
        ///
        /// <param name="image">Source image data to process.</param>
        ///
        /// <returns>Returns list of found interest points.</returns>
        ///
        /// <exception cref="UnsupportedImageFormatException">
        ///   The source image has incorrect pixel format.
        /// </exception>
        ///
        public List <SurfPoint> ProcessImage(UnmanagedImage image)
        {
            // check image format
            if (
                (image.PixelFormat != PixelFormat.Format8bppIndexed) &&
                (image.PixelFormat != PixelFormat.Format24bppRgb) &&
                (image.PixelFormat != PixelFormat.Format32bppRgb) &&
                (image.PixelFormat != PixelFormat.Format32bppArgb)
                )
            {
                throw new UnsupportedImageFormatException("Unsupported pixel format of the source 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. Compute interest point response map
            if (responses == null ||
                image.Width != responses.Width || image.Height != responses.Height)
            {
                responses = new ResponseFilters(image.Width, image.Height, octaves, initial);
            }

            responses.Compute(integral);


            // 3. Suppress non-maximum points
            List <SurfPoint> featureList = new List <SurfPoint>();

            // 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 mscale = mid.Width / top.Width;
                int bscale = bot.Width / top.Width;

                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++)
                    {
                        float 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 SurfPoint(
                                                    (float)((x + offset[0]) * tstep),
                                                    (float)((y + offset[1]) * tstep),
                                                    (float)(0.1333f * (mid.Size + offset[2] * mstep)),
                                                    mid.Laplacian[y * mscale, x * mscale]));
                            }
                        }
                    }
                }
            }

            return(featureList);
        }
コード例 #4
0
        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);
        }