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); } } }
/** * 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); } } }