/**
         * Detect scale-invariant feature points given a pyramid.
         * @param _i_dog_feature_points
         * 検出したDOG特徴点
         */
        public void detect(GaussianScaleSpacePyramid i_pyramid, DogFeaturePointStack i_dog_feature_points)
        {
            //clean up 1st feature stack
            DogFeaturePointStack tmp_fp = this._tmp_fps;

            tmp_fp.clear();

            // Compute Laplacian images (DoG)
            this.mLaplacianPyramid.compute(i_pyramid);

            // Detect minima and maximum in Laplacian images
            this.extractFeatures(i_pyramid, this.mLaplacianPyramid, tmp_fp);

            // Sub-pixel refinement
            this.findSubpixelLocations(i_pyramid, tmp_fp);

            // Compute the gradient pyramid
            this.mOrientationAssignment.computeGradients(i_pyramid);

            AreaBuckit abuckit = this.mBuckets;


            if (tmp_fp.getLength() <= abuckit._buckit.Length)
            {
                //特徴点の数が要求数以下なら全てのポイントを使う。
                for (int i = 0; i < tmp_fp.getLength(); i++)
                {
                    this.addFeatureOrientations(i_pyramid, tmp_fp.getItem(i), i_dog_feature_points);
                }
            }
            else
            {
                //特徴点を選別(Prune features)

                // Clear the previous state
                abuckit.clear();

                // Insert each features into a bucket
                for (int i = 0; i < tmp_fp.getLength(); i++)
                {
                    DogFeaturePoint p = tmp_fp.getItem(i);
                    abuckit.put(p.x, p.y, i, Math.Abs(p.score));
                }
                // Compute an orientation for each feature point
                for (int i = 0; i < abuckit._buckit.Length; i++)
                {
                    if (abuckit._buckit[i].first == 0)
                    {
                        continue;
                    }
                    this.addFeatureOrientations(i_pyramid, tmp_fp.getItem(abuckit._buckit[i].second), i_dog_feature_points);
                }
            }

            return;
        }
 public DoGScaleInvariantDetector(int i_width, int i_height, int i_octerv, int i_num_of_scale_of_octerv, double i_LaplacianThreshold,
                                  double i_EdgeThreshold, int i_MaxNumFeaturePoints)
 {
     this.mLaplacianThreshold     = i_LaplacianThreshold;
     this.mEdgeThreshold          = i_EdgeThreshold;
     this.mMaxSubpixelDistanceSqr = (3 * 3);
     this.mOrientations           = new double[kMaxNumOrientations];
     this.mLaplacianPyramid       = new DoGPyramid(i_width, i_height, i_octerv, i_num_of_scale_of_octerv - 1);
     this.mOrientationAssignment  = new OrientationAssignment(i_width, i_height, i_octerv, i_num_of_scale_of_octerv, kMaxNumOrientations, 3, 1.5f, 5, 0.8f);
     this.mBuckets = new AreaBuckit(i_width, i_height, 10, 10, i_MaxNumFeaturePoints);
     this._tmp_fps = new DogFeaturePointStack(kMaxNumFeaturePoints);
 }