public OrientationAssignment(int fine_width, int fine_height, int num_octaves, int num_scales_per_octave,
                                     int num_bins, double gaussian_expansion_factor, double support_region_expansion_factor,
                                     int num_smoothing_iterations, double peak_threshold)
        {
            this.mNumScalesPerOctave           = num_scales_per_octave;
            this.mGaussianExpansionFactor      = gaussian_expansion_factor;
            this.mSupportRegionExpansionFactor = support_region_expansion_factor;
            this.mNumSmoothingIterations       = num_smoothing_iterations;
            this.mPeakThreshold = peak_threshold;

            this.mHistogram = new BilinearHistogram(num_bins);

            // Allocate gradient images
            this.mGradients = new GradientsImage_ARTK[num_octaves * this.mNumScalesPerOctave];
            for (int i = 0; i < num_octaves; i++)
            {
                for (int j = 0; j < num_scales_per_octave; j++)
                {
                    this.mGradients[i * num_scales_per_octave + j] = new GradientsImage_O1(fine_width >> i, fine_height >> i);
                }
            }
        }
Example #2
0
        /**
         * OrientationAssignment.computeの一部
         * @param x
         * @param y
         * @param radius
         * @param gw_scale
         * @param i_histogram
         */
        virtual public void buildOrientationHistogram(double x, double y, double radius, double gw_scale, BilinearHistogram i_histogram)
        {
            double[] a_buf = this._angle;
            double[] m_buf = this._mag;
            int      xi    = (int)(x + 0.5f);
            int      yi    = (int)(y + 0.5f);
            // Box around feature point
            int x0 = xi - (int)(radius + 0.5f);
            int x1 = xi + (int)(radius + 0.5f);
            int y0 = yi - (int)(radius + 0.5f);
            int y1 = yi + (int)(radius + 0.5f);

            // Clip the box to be within the bounds of the image
            int width_1  = this._size.w - 1;
            int height_1 = this._size.h - 1;

            if (x0 < 0)
            {
                x0 = 0;
            }                      //x0 = math_utils.max2(0, x0);
            if (x1 > width_1)
            {
                x1 = width_1;
            }                                  //x1 = math_utils.min2(x1, (int) g.getWidth() - 1);
            if (y0 < 0)
            {
                y0 = 0;
            }                      //y0 = math_utils.max2(0, y0);
            if (y1 > height_1)
            {
                y1 = height_1;
            }                                    //y1 = math_utils.min2(y1, (int) g.getHeight() - 1);

            double radius2 = Math.Ceiling(radius * radius);

            // Build up the orientation histogram
            for (int yp = y0; yp <= y1; yp++)
            {
                double dy  = yp - y;
                double dy2 = (dy * dy);

                int y_ptr = this._size.w * yp;

                for (int xp = x0; xp <= x1; xp++)
                {
                    double dx = xp - x;
                    double r2 = (dx * dx) + dy2;

                    // Only use the gradients within the circular window
                    if (r2 > radius2)
                    {
                        continue;
                    }
                    int    g2_ptr = y_ptr + xp;    // const float* g = &y_ptr[xp<<1];
                    double angle  = a_buf[g2_ptr]; // const float& angle = g[0];
                    double mag    = m_buf[g2_ptr]; // const float& mag = g[1];

                    // Compute the gaussian weight based on distance from center of keypoint
                    double w = FastMath.fastexp6(r2 * gw_scale);


                    // Vote to the orientation histogram with a bilinear update
                    i_histogram.bilinearHistogramUpdate(angle, w * mag);
                }
            }
        }