2
votes

In OpenCV4Android, I'm using the DENSE feature detector that lays a grid of points over the image. Next, I want to compute the descriptors for those keypoints. For this I tried to use the ORB descriptor extractor.

    mDetector = FeatureDetector.create(FeatureDetector.DENSE);
    mExtractor = DescriptorExtractor.create(DescriptorExtractor.ORB);

    MatOfKeyPoint pointsmat0 = new MatOfKeyPoint();
    Mat descriptors0 = new Mat();

    mDetector.detect(image0, pointsmat0);
    mExtractor.compute(image0, pointsmat0, descriptors0);

Now, when outputting pointsmat0.total and descriptors0.rows() these amounts should be equal, because the descriptor extractor should remove keypoints for which no descriptor could be computed. However, this is not the case.

I get:

pointsmat0.total() around 10000
descrpitors0.rows() around 8000

I've tried using the BRIEF descriptor extractor, but this has the same problem. So, DENSE+ORB / DENSE+BRIEF has this problem.

When I run this sample with ORB+ORB the number of keypoints is equal to the number of descriptors (500 both). So, the question: Which descriptor extractor can be used with DENSE?

1

1 Answers

1
votes

No need to stop using ORB for that alone. The decrease in the number of descriptors is because ORB filters the input keypoints when they are too close to the border of the image.

From the code of ORB (C++ implementation):

void ORB::operator()( InputArray _image, InputArray _mask, vector<KeyPoint>& _keypoints,
                      OutputArray _descriptors, bool useProvidedKeypoints) const
{
    [...]
    if( do_keypoints )
    {
        // Get keypoints, those will be far enough from the border that
        // no check will be required for the descriptor
        computeKeyPoints(imagePyramid, maskPyramid, allKeypoints,
                         nfeatures, firstLevel, scaleFactor,
                         edgeThreshold, patchSize, scoreType);
    }
    else
    {
        // Remove keypoints very close to the border
        KeyPointsFilter::runByImageBorder(_keypoints, image.size(), edgeThreshold);

        [...]
    }

However, keep in mind that you will have problems with the angle of the points.