/**
         * 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;
        }
        /**
         * Sub-pixel refinement.
         */
        private void findSubpixelLocations(GaussianScaleSpacePyramid pyramid, DogFeaturePointStack i_dog_fp)
        {
            int    num_points;
            double laplacianSqrThreshold;
            double hessianThreshold;

            num_points            = 0;
            laplacianSqrThreshold = (this.mLaplacianThreshold * this.mLaplacianThreshold);
            double te = (mEdgeThreshold + 1);

            hessianThreshold = ((te * te) / mEdgeThreshold);

            for (int i = 0; i < i_dog_fp.getLength(); i++)
            {
                DogFeaturePoint kp = i_dog_fp.getItem(i);
                //assert kp.scale < mLaplacianPyramid.numScalePerOctave();
                // ASSERT(kp.scale < mLaplacianPyramid.numScalePerOctave(),
                // "Feature point scale is out of bounds");
                int lap_index = kp.octave * mLaplacianPyramid.numScalePerOctave() + kp.scale;

                // Get Laplacian images
                LaplacianImage lap0 = mLaplacianPyramid.get(lap_index - 1);
                LaplacianImage lap1 = mLaplacianPyramid.get(lap_index);
                LaplacianImage lap2 = mLaplacianPyramid.get(lap_index + 1);

                // Compute the Hessian
                if (!this.updateLocation(kp, lap0, lap1, lap2))
                {
                    continue;
                }


                if (Math.Abs(kp.edge_score) < hessianThreshold && (kp.score * kp.score) >= laplacianSqrThreshold &&
                    kp.x >= 0 && kp.x < mLaplacianPyramid.get(0).getWidth() && kp.y >= 0 &&
                    kp.y < mLaplacianPyramid.get(0).getHeight())
                {
                    // Update the sigma
                    kp.sigma = pyramid.effectiveSigma(kp.octave, kp.sp_scale);
                    i_dog_fp.swap(i, num_points++);
                }
            }
            i_dog_fp.setLength(num_points);
        }
Exemplo n.º 3
0
        /**
         * Extract the descriptors for all the feature points.
         */
        private void ExtractFREAK84(FreakFeaturePointStack store,
                                    GaussianScaleSpacePyramid pyramid, DogFeaturePointStack points,
                                    double[] points_ring0, double[] points_ring1, double[] points_ring2,
                                    double[] points_ring3, double[] points_ring4, double[] points_ring5,
                                    double sigma_center, double sigma_ring0, double sigma_ring1,
                                    double sigma_ring2, double sigma_ring3, double sigma_ring4,
                                    double sigma_ring5, double expansion_factor)
        {
            // ASSERT(pyramid, "Pyramid is NULL");
            // ASSERT(store.size() == points.size(),
            // "Feature store has not been allocated");
            for (int i = 0; i < points.getLength(); i++)
            {
                FreakFeaturePoint sp = store.prePush();
                if (sp == null)
                {
                    prepush_wawning();
                    break;
                }
                DogFeaturePoint pt = points.getItem(i);
                if (!ExtractFREAK84(sp.descripter,
                                    pyramid, pt, points_ring0, points_ring1,
                                    points_ring2, points_ring3, points_ring4, points_ring5,
                                    sigma_center, sigma_ring0, sigma_ring1, sigma_ring2,
                                    sigma_ring3, sigma_ring4, sigma_ring5, expansion_factor

                                    ))
                {
                    store.pop();
                    continue;
                }
                sp.angle  = pt.angle;
                sp.x      = pt.x;
                sp.y      = pt.y;
                sp.scale  = pt.sigma;
                sp.maxima = pt.score > 0;
                //			store.point(num_points).set(points[i]);
            }
        }