Exemplo n.º 1
0
        /// <summary>
        /// Build Hessian Matrix
        /// </summary>
        /// <param name="octave"></param>
        /// <param name="interval"></param>
        /// <param name="row"></param>
        /// <param name="column"></param>
        /// <returns>3x3 Matrix of Second Order Derivatives</returns>
        private double[,] BuildHessian(int r, int c, ResponseLayer t, ResponseLayer m, ResponseLayer b)
        {
            double v, dxx, dyy, dss, dxy, dxs, dys;

            v   = m.getResponse(r, c, t);
            dxx = m.getResponse(r, c + 1, t) + m.getResponse(r, c - 1, t) - 2 * v;
            dyy = m.getResponse(r + 1, c, t) + m.getResponse(r - 1, c, t) - 2 * v;
            dss = t.getResponse(r, c) + b.getResponse(r, c, t) - 2 * v;
            dxy = (m.getResponse(r + 1, c + 1, t) - m.getResponse(r + 1, c - 1, t) -
                   m.getResponse(r - 1, c + 1, t) + m.getResponse(r - 1, c - 1, t)) / 4f;
            dxs = (t.getResponse(r, c + 1) - t.getResponse(r, c - 1) -
                   b.getResponse(r, c + 1, t) + b.getResponse(r, c - 1, t)) / 4f;
            dys = (t.getResponse(r + 1, c) - t.getResponse(r - 1, c) -
                   b.getResponse(r + 1, c, t) + b.getResponse(r - 1, c, t)) / 4f;

            double[,] H = new double[3, 3];
            H[0, 0]     = dxx;
            H[0, 1]     = dxy;
            H[0, 2]     = dxs;
            H[1, 0]     = dxy;
            H[1, 1]     = dyy;
            H[1, 2]     = dys;
            H[2, 0]     = dxs;
            H[2, 1]     = dys;
            H[2, 2]     = dss;
            return(H);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Проверка для указанной точки, является ли она локальным максимумом
        /// Гессиана по сравнению с окружающими точками на одном с ней слое,
        /// с точками на слое масштаба больше и на слое масштаба меньше для октавы.
        /// (Метод соседних точек 3x3x3)
        /// </summary>
        /// <param name="r">Строка</param>
        /// <param name="c">Колонка</param>
        /// <param name="t">Верхний слой </param>
        /// <param name="m">Средний слой</param>
        /// <param name="b">Нижний слой</param>
        /// <returns></returns>
        bool isExtremum(int r, int c, ResponseLayer t, ResponseLayer m, ResponseLayer b)
        {
            // проверка границ
            int layerBorder = (t.filter + 1) / (2 * t.step);

            if (r <= layerBorder || r >= t.height - layerBorder || c <= layerBorder || c >= t.width - layerBorder)
            {
                return(false);
            }

            // проверить, что значение в точки среднего слоя больше порогового значения
            float candidate = m.getResponse(r, c, t);

            if (candidate < thresh)
            {
                return(false);
            }

            for (int rr = -1; rr <= 1; ++rr)
            {
                for (int cc = -1; cc <= 1; ++cc)
                {
                    // Если любой из соседей 3x3x3 больше, то это не экстремум
                    if (t.getResponse(r + rr, c + cc) >= candidate ||
                        ((rr != 0 || cc != 0) && m.getResponse(r + rr, c + cc, t) >= candidate) ||
                        b.getResponse(r + rr, c + cc, t) >= candidate)
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
Exemplo n.º 3
0
        /// <summary>
        ///   Test whether the point (r,c) in the middle layer
        ///   is a local maximum in the <c>3x3x3</c> neighborhood.
        /// </summary>
        ///
        /// <param name="r">The row to be tested.</param>
        /// <param name="c">The column to be tested.</param>
        ///
        /// <param name="t">Top response layer.</param>
        /// <param name="m">Middle response layer.</param>
        /// <param name="b">Bottom response layer.</param>
        ///
        bool isExtremum(int r, int c, ResponseLayer t, ResponseLayer m, ResponseLayer b)
        {
            // bounds check
            int layerBorder = (t.filter + 1) / (2 * t.step);

            if (r <= layerBorder || r >= t.height - layerBorder || c <= layerBorder || c >= t.width - layerBorder)
            {
                return(false);
            }

            // check the candidate point in the middle layer is above thresh
            float candidate = m.getResponse(r, c, t);

            if (candidate < thresh)
            {
                return(false);
            }

            for (int rr = -1; rr <= 1; ++rr)
            {
                for (int cc = -1; cc <= 1; ++cc)
                {
                    // if any response in 3x3x3 is greater candidate not maximum
                    if (t.getResponse(r + rr, c + cc) >= candidate ||
                        ((rr != 0 || cc != 0) && m.getResponse(r + rr, c + cc, t) >= candidate) ||
                        b.getResponse(r + rr, c + cc, t) >= candidate)
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Build Matrix of First Order Scale-Space derivatives
        /// </summary>
        /// <param name="octave"></param>
        /// <param name="interval"></param>
        /// <param name="row"></param>
        /// <param name="column"></param>
        /// <returns>3x1 Matrix of Derivatives</returns>
        private double[,] BuildDerivative(int r, int c, ResponseLayer t, ResponseLayer m, ResponseLayer b)
        {
            double dx, dy, ds;

            dx = (m.getResponse(r, c + 1, t) - m.getResponse(r, c - 1, t)) / 2f;
            dy = (m.getResponse(r + 1, c, t) - m.getResponse(r - 1, c, t)) / 2f;
            ds = (t.getResponse(r, c) - b.getResponse(r, c, t)) / 2f;

            double[,] D = { { dx }, { dy }, { ds } };
            return(D);
        }
        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));
        }
Exemplo n.º 6
0
        /// <summary>
        /// Вычислить значения гессианов для указанного слоя масштаба
        /// </summary>
        private void buildResponseLayer(ResponseLayer rl)
        {
            int   step = rl.step;                    // размер шага для фильтра
            int   b = (rl.filter - 1) / 2;           // граница фильтра
            int   l = rl.filter / 3;                 // доля для фильтра (размер фильтра / 3)
            int   w = rl.filter;                     // размер фильтра
            float inverse_area = 1f / (w * w);       // нормализация
            float Dxx, Dyy, Dxy;

            for (int r, c, ar = 0, index = 0; ar < rl.height; ++ar)
            {
                for (int ac = 0; ac < rl.width; ++ac, index++)
                {
                    // получить координаты изображения
                    r = ar * step;
                    c = ac * step;

                    // Вычислить компоненты
                    Dxx = img.BoxIntegral(r - l + 1, c - b, 2 * l - 1, w)
                          - img.BoxIntegral(r - l + 1, c - l / 2, 2 * l - 1, l) * 3;
                    Dyy = img.BoxIntegral(r - b, c - l + 1, w, 2 * l - 1)
                          - img.BoxIntegral(r - l / 2, c - l + 1, l, 2 * l - 1) * 3;
                    Dxy = +img.BoxIntegral(r - l, c + 1, l, l)
                          + img.BoxIntegral(r + 1, c - l, l, l)
                          - img.BoxIntegral(r - l, c - l, l, l)
                          - img.BoxIntegral(r + 1, c + 1, l, l);

                    // Нормализовать фильтры с учетом их размеров
                    Dxx *= inverse_area;
                    Dyy *= inverse_area;
                    Dxy *= inverse_area;

                    // Получить значение гессиана и лапласиана
                    rl.responses[index] = (Dxx * Dyy - 0.81f * Dxy * Dxy);
                    rl.laplacian[index] = (byte)(Dxx + Dyy >= 0 ? 1 : 0);
                }
            }
        }
Exemplo n.º 7
0
        /// <summary>
        /// Build Responses for a given ResponseLayer
        /// </summary>
        /// <param name="rl"></param>
        private void buildResponseLayer(ResponseLayer rl)
        {
            int   step = rl.step;                    // step size for this filter
            int   b = (rl.filter - 1) / 2;           // border for this filter
            int   l = rl.filter / 3;                 // lobe for this filter (filter size / 3)
            int   w = rl.filter;                     // filter size
            float inverse_area = 1f / (w * w);       // normalization factor
            float Dxx, Dyy, Dxy;

            for (int r, c, ar = 0, index = 0; ar < rl.height; ++ar)
            {
                for (int ac = 0; ac < rl.width; ++ac, index++)
                {
                    // get the image coordinates
                    r = ar * step;
                    c = ac * step;

                    // Compute response components
                    Dxx = img.BoxIntegral(r - l + 1, c - b, 2 * l - 1, w)
                          - img.BoxIntegral(r - l + 1, c - l / 2, 2 * l - 1, l) * 3;
                    Dyy = img.BoxIntegral(r - b, c - l + 1, w, 2 * l - 1)
                          - img.BoxIntegral(r - l / 2, c - l + 1, l, 2 * l - 1) * 3;
                    Dxy = +img.BoxIntegral(r - l, c + 1, l, l)
                          + img.BoxIntegral(r + 1, c - l, l, l)
                          - img.BoxIntegral(r - l, c - l, l, l)
                          - img.BoxIntegral(r + 1, c + 1, l, l);

                    // Normalize the filter responses with respect to their size
                    Dxx *= inverse_area;
                    Dyy *= inverse_area;
                    Dxy *= inverse_area;

                    // Get the determinant of Hessian response & Laplacian sign
                    rl.responses[index] = (Dxx * Dyy - 0.81f * Dxy * Dxy);
                    rl.laplacian[index] = (byte)(Dxx + Dyy >= 0 ? 1 : 0);
                }
            }
        }
Exemplo n.º 8
0
        /// <summary>
        /// Интерполирование найденных Гессианов соседей 3x3x3
        /// </summary>
        void interpolateExtremum(int r, int c, ResponseLayer t, ResponseLayer m, ResponseLayer b)
        {
            Matrix D  = Matrix.Create(BuildDerivative(r, c, t, m, b));
            Matrix H  = Matrix.Create(BuildHessian(r, c, t, m, b));
            Matrix Hi = H.Inverse();
            Matrix Of = -1 * Hi * D;

            double[] O = { Of[0, 0], Of[1, 0], Of[2, 0] };

            // шаг между фильтрами
            int filterStep = (m.filter - b.filter);

            // если точка достаточно близка к фактическому экстремуму
            if (Math.Abs(O[0]) < 0.5f && Math.Abs(O[1]) < 0.5f && Math.Abs(O[2]) < 0.5f)
            {
                InterestPoint iPoint = new InterestPoint();
                iPoint.x         = (float)((c + O[0]) * t.step);
                iPoint.y         = (float)((r + O[1]) * t.step);
                iPoint.scale     = (float)((0.1333f) * (m.filter + O[2] * filterStep));
                iPoint.laplacian = (int)(m.getLaplacian(r, c, t));
                iPoints.Add(iPoint);
            }
        }
Exemplo n.º 9
0
        /// <summary>
        ///   Interpolate scale-space maximum points to subpixel accuracy to form an image feature.
        /// </summary>
        ///
        /// <param name="r">The row to be tested.</param>
        /// <param name="c">The column to be tested.</param>
        ///
        /// <param name="t">Top response layer.</param>
        /// <param name="m">Middle response layer.</param>
        /// <param name="b">Bottom response layer.</param>
        ///
        void interpolateExtremum(int r, int c, ResponseLayer t, ResponseLayer m, ResponseLayer b)
        {
            var D  = BuildDerivative(r, c, t, m, b);
            var H  = BuildHessian(r, c, t, m, b);
            var Hi = Matrix.Inverse(H);
            var Of = (-1.0).Multiply(Hi).Multiply(D);

            // get the offsets from the interpolation
            double[] O = { Of[0, 0], Of[1, 0], Of[2, 0] };

            // get the step distance between filters
            int filterStep = (m.filter - b.filter);

            // If point is sufficiently close to the actual extremum
            if (Math.Abs(O[0]) < 0.5f && Math.Abs(O[1]) < 0.5f && Math.Abs(O[2]) < 0.5f)
            {
                IPoint ipt = new IPoint();
                ipt.x         = (float)((c + O[0]) * t.step);
                ipt.y         = (float)((r + O[1]) * t.step);
                ipt.scale     = (float)((0.1333f) * (m.filter + O[2] * filterStep));
                ipt.laplacian = (int)(m.getLaplacian(r, c, t));
                ipts.Add(ipt);
            }
        }
Exemplo n.º 10
0
        /// <summary>
        /// Interpolate scale-space extrema to subpixel accuracy to form an image feature
        /// </summary>
        /// <param name="r"></param>
        /// <param name="c"></param>
        /// <param name="t"></param>
        /// <param name="m"></param>
        /// <param name="b"></param>
        void interpolateExtremum(int r, int c, ResponseLayer t, ResponseLayer m, ResponseLayer b)
        {
            Matrix D = Matrix.Create(BuildDerivative(r, c, t, m, b));
              Matrix H = Matrix.Create(BuildHessian(r, c, t, m, b));
              Matrix Hi = H.Inverse();
              Matrix Of = -1 * Hi * D;

              // get the offsets from the interpolation
              double[] O = { Of[0, 0], Of[1, 0], Of[2, 0] };

              // get the step distance between filters
              int filterStep = (m.filter - b.filter);

              // If point is sufficiently close to the actual extremum
              if (Math.Abs(O[0]) < 0.5f && Math.Abs(O[1]) < 0.5f && Math.Abs(O[2]) < 0.5f)
              {
            IPoint ipt = new IPoint();
            ipt.x = (float)((c + O[0]) * t.step);
            ipt.y = (float)((r + O[1]) * t.step);
            ipt.scale = (float)((0.1333f) * (m.filter + O[2] * filterStep));
            ipt.laplacian = (int)(m.getLaplacian(r,c,t));
            ipts.Add(ipt);
              }
        }
Exemplo n.º 11
0
        /// <summary>
        /// Build Hessian Matrix 
        /// </summary>
        /// <param name="octave"></param>
        /// <param name="interval"></param>
        /// <param name="row"></param>
        /// <param name="column"></param>
        /// <returns>3x3 Matrix of Second Order Derivatives</returns>
        private double[,] BuildHessian(int r, int c, ResponseLayer t, ResponseLayer m, ResponseLayer b)
        {
            double v, dxx, dyy, dss, dxy, dxs, dys;

              v = m.getResponse(r, c, t);
              dxx = m.getResponse(r, c + 1, t) + m.getResponse(r, c - 1, t) - 2 * v;
              dyy = m.getResponse(r + 1, c, t) + m.getResponse(r - 1, c, t) - 2 * v;
              dss = t.getResponse(r, c) + b.getResponse(r, c, t) - 2 * v;
              dxy = (m.getResponse(r + 1, c + 1, t) - m.getResponse(r + 1, c - 1, t) -
              m.getResponse(r - 1, c + 1, t) + m.getResponse(r - 1, c - 1, t)) / 4f;
              dxs = (t.getResponse(r, c + 1) - t.getResponse(r, c - 1) -
              b.getResponse(r, c + 1, t) + b.getResponse(r, c - 1, t)) / 4f;
              dys = (t.getResponse(r + 1, c) - t.getResponse(r - 1, c) -
              b.getResponse(r + 1, c, t) + b.getResponse(r - 1, c, t)) / 4f;

              double[,] H = new double[3, 3];
              H[0, 0] = dxx;
              H[0, 1] = dxy;
              H[0, 2] = dxs;
              H[1, 0] = dxy;
              H[1, 1] = dyy;
              H[1, 2] = dys;
              H[2, 0] = dxs;
              H[2, 1] = dys;
              H[2, 2] = dss;
              return H;
        }
Exemplo n.º 12
0
        /// <summary>
        /// Build Responses for a given ResponseLayer
        /// </summary>
        /// <param name="rl"></param>
        private void buildResponseLayer(ResponseLayer rl)
        {
            int step = rl.step;                      // step size for this filter
              int b = (rl.filter - 1) / 2;             // border for this filter
              int l = rl.filter / 3;                   // lobe for this filter (filter size / 3)
              int w = rl.filter;                       // filter size
              float inverse_area = 1f / (w * w);       // normalisation factor
              float Dxx, Dyy, Dxy;

              for (int r, c, ar = 0, index = 0; ar < rl.height; ++ar)
              {
            for (int ac = 0; ac < rl.width; ++ac, index++)
            {
              // get the image coordinates
              r = ar * step;
              c = ac * step;

              // Compute response components
              Dxx = img.BoxIntegral(r - l + 1, c - b, 2 * l - 1, w)
              - img.BoxIntegral(r - l + 1, c - l / 2, 2 * l - 1, l) * 3;
              Dyy = img.BoxIntegral(r - b, c - l + 1, w, 2 * l - 1)
              - img.BoxIntegral(r - l / 2, c - l + 1, l, 2 * l - 1) * 3;
              Dxy = + img.BoxIntegral(r - l, c + 1, l, l)
                + img.BoxIntegral(r + 1, c - l, l, l)
                - img.BoxIntegral(r - l, c - l, l, l)
                - img.BoxIntegral(r + 1, c + 1, l, l);

              // Normalise the filter responses with respect to their size
              Dxx *= inverse_area;
              Dyy *= inverse_area;
              Dxy *= inverse_area;

              // Get the determinant of hessian response & laplacian sign
              rl.responses[index] = (Dxx * Dyy - 0.81f * Dxy * Dxy);
              rl.laplacian[index] = (byte)(Dxx + Dyy >= 0 ? 1 : 0);
            }
              }
        }
Exemplo n.º 13
0
            public float getResponse(int row, int column, ResponseLayer src)
            {
                int scale = this.width / src.width;

                return(responses[(scale * row) * width + (scale * column)]);
            }
Exemplo n.º 14
0
        /// <summary>
        /// Build Matrix of First Order Scale-Space derivatives
        /// </summary>
        /// <param name="octave"></param>
        /// <param name="interval"></param>
        /// <param name="row"></param>
        /// <param name="column"></param>
        /// <returns>3x1 Matrix of Derivatives</returns>
        private double[,] BuildDerivative(int r, int c, ResponseLayer t, ResponseLayer m, ResponseLayer b)
        {
            double dx, dy, ds;

              dx = (m.getResponse(r, c + 1, t) - m.getResponse(r, c - 1, t)) / 2f;
              dy = (m.getResponse(r + 1, c, t) - m.getResponse(r - 1, c, t)) / 2f;
              ds = (t.getResponse(r, c) - b.getResponse(r, c, t)) / 2f;

              double[,] D = { { dx }, { dy }, { ds } };
              return D;
        }
Exemplo n.º 15
0
        /// <summary>
        /// Проверка для указанной точки, является ли она локальным максимумом 
        /// Гессиана по сравнению с окружающими точками на одном с ней слое, 
        /// с точками на слое масштаба больше и на слое масштаба меньше для октавы. 
        /// (Метод соседних точек 3x3x3)
        /// </summary>
        /// <param name="r">Строка</param>
        /// <param name="c">Колонка</param>
        /// <param name="t">Верхний слой </param>
        /// <param name="m">Средний слой</param>
        /// <param name="b">Нижний слой</param>
        /// <returns></returns>
        bool isExtremum(int r, int c, ResponseLayer t, ResponseLayer m, ResponseLayer b)
        {
            // проверка границ
            int layerBorder = (t.filter + 1) / (2 * t.step);
            if (r <= layerBorder || r >= t.height - layerBorder || c <= layerBorder || c >= t.width - layerBorder)
                return false;

            // проверить, что значение в точки среднего слоя больше порогового значения
            float candidate = m.getResponse(r, c, t);
            if (candidate < thresh)
                return false;

            for (int rr = -1; rr <= 1; ++rr)
            {
                for (int cc = -1; cc <= 1; ++cc)
                {
                    // Если любой из соседей 3x3x3 больше, то это не экстремум
                    if (t.getResponse(r + rr, c + cc) >= candidate ||
                      ((rr != 0 || cc != 0) && m.getResponse(r + rr, c + cc, t) >= candidate) ||
                      b.getResponse(r + rr, c + cc, t) >= candidate)
                    {
                        return false;
                    }
                }
            }

            return true;
        }
        public List <SpeededUpRobustFeaturePoint> 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. 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 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++)
                    {
                        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);
        }
Exemplo n.º 17
0
        /// <summary>
        /// Интерполирование найденных Гессианов соседей 3x3x3
        /// </summary>
        void interpolateExtremum(int r, int c, ResponseLayer t, ResponseLayer m, ResponseLayer b)
        {
            Matrix D = Matrix.Create(BuildDerivative(r, c, t, m, b));
            Matrix H = Matrix.Create(BuildHessian(r, c, t, m, b));
            Matrix Hi = H.Inverse();
            Matrix Of = -1 * Hi * D;

            double[] O = { Of[0, 0], Of[1, 0], Of[2, 0] };

            // шаг между фильтрами
            int filterStep = (m.filter - b.filter);

            // если точка достаточно близка к фактическому экстремуму
            if (Math.Abs(O[0]) < 0.5f && Math.Abs(O[1]) < 0.5f && Math.Abs(O[2]) < 0.5f)
            {
                InterestPoint iPoint = new InterestPoint();
                iPoint.x = (float)((c + O[0]) * t.step);
                iPoint.y = (float)((r + O[1]) * t.step);
                iPoint.scale = (float)((0.1333f) * (m.filter + O[2] * filterStep));
                iPoint.laplacian = (int)(m.getLaplacian(r, c, t));
                iPoints.Add(iPoint);
            }
        }
Exemplo n.º 18
0
 public float getResponse(int row, int column, ResponseLayer src)
 {
     int scale = this.width / src.width;
     return responses[(scale * row) * width + (scale * column)];
 }
Exemplo n.º 19
0
        /// <summary>
        /// Test whether the point r,c in the middle layer is extremum in 3x3x3 neighbourhood
        /// </summary>
        /// <param name="r">Row to be tested</param>
        /// <param name="c">Column to be tested</param>
        /// <param name="t">Top ReponseLayer</param>
        /// <param name="m">Middle ReponseLayer</param>
        /// <param name="b">Bottome ReponseLayer</param>
        /// <returns></returns>
        bool isExtremum(int r, int c, ResponseLayer t, ResponseLayer m, ResponseLayer b)
        {
            // bounds check
              int layerBorder = (t.filter + 1) / (2 * t.step);
              if (r <= layerBorder || r >= t.height - layerBorder || c <= layerBorder || c >= t.width - layerBorder)
            return false;

              // check the candidate point in the middle layer is above thresh
              float candidate = m.getResponse(r, c, t);
              if (candidate < thresh)
            return false;

              for (int rr = -1; rr <= 1; ++rr)
              {
            for (int cc = -1; cc <= 1; ++cc)
            {
              // if any response in 3x3x3 is greater candidate not maximum
              if (t.getResponse(r + rr, c + cc) >= candidate ||
            ((rr != 0 || cc != 0) && m.getResponse(r + rr, c + cc, t) >= candidate) ||
            b.getResponse(r + rr, c + cc, t) >= candidate)
              {
            return false;
              }
            }
              }

              return true;
        }
Exemplo n.º 20
0
 public byte getLaplacian(int row, int column, ResponseLayer src)
 {
     int scale = this.width / src.width;
     return laplacian[(scale * row) * width + (scale * column)];
 }
Exemplo n.º 21
0
            public byte getLaplacian(int row, int column, ResponseLayer src)
            {
                int scale = this.width / src.width;

                return(laplacian[(scale * row) * width + (scale * column)]);
            }
 private string GetResponseFromLayer(ResponseLayer responseLayer, int quality)
 {
     return(this.GetDialogueOfQuality(responseLayer.npcDialogue, quality));
 }
Exemplo n.º 23
0
        /// <summary>
        /// Вычислить значения гессианов для указанного слоя масштаба
        /// </summary>
        private void buildResponseLayer(ResponseLayer rl)
        {
            int step = rl.step;                      // размер шага для фильтра
            int b = (rl.filter - 1) / 2;             // граница фильтра
            int l = rl.filter / 3;                   // доля для фильтра (размер фильтра / 3)
            int w = rl.filter;                       // размер фильтра
            float inverse_area = 1f / (w * w);       // нормализация
            float Dxx, Dyy, Dxy;

            for (int r, c, ar = 0, index = 0; ar < rl.height; ++ar)
            {
                for (int ac = 0; ac < rl.width; ++ac, index++)
                {
                    // получить координаты изображения
                    r = ar * step;
                    c = ac * step;

                    // Вычислить компоненты
                    Dxx = img.BoxIntegral(r - l + 1, c - b, 2 * l - 1, w)
                        - img.BoxIntegral(r - l + 1, c - l / 2, 2 * l - 1, l) * 3;
                    Dyy = img.BoxIntegral(r - b, c - l + 1, w, 2 * l - 1)
                        - img.BoxIntegral(r - l / 2, c - l + 1, l, 2 * l - 1) * 3;
                    Dxy = +img.BoxIntegral(r - l, c + 1, l, l)
                          + img.BoxIntegral(r + 1, c - l, l, l)
                          - img.BoxIntegral(r - l, c - l, l, l)
                          - img.BoxIntegral(r + 1, c + 1, l, l);

                    // Нормализовать фильтры с учетом их размеров
                    Dxx *= inverse_area;
                    Dyy *= inverse_area;
                    Dxy *= inverse_area;

                    // Получить значение гессиана и лапласиана
                    rl.responses[index] = (Dxx * Dyy - 0.81f * Dxy * Dxy);
                    rl.laplacian[index] = (byte)(Dxx + Dyy >= 0 ? 1 : 0);
                }
            }
        }