c++opencvkeypointfeature-descriptor

KeyPoint descriptor OpenCV


I am trying to understand how to get the descriptor for a given KeyPoint in OpenCV. So far my code looks like follows:

#include <iostream>
#include "opencv2/opencv.hpp"

typedef cv::Mat Image;

int main(int argc, const char * argv[])
{

    Image imgA = cv::imread("images/buddhamulticam_total100.png",
                              CV_LOAD_IMAGE_GRAYSCALE);
    Image imgB = cv::imread("images/buddhamulticam_total101.png", 
                            CV_LOAD_IMAGE_GRAYSCALE);

    cv::Ptr<cv::FeatureDetector> detector = 
                    cv::FeatureDetector::create("ORB");
    cv::Ptr<cv::DescriptorExtractor> descriptor = 
                    cv::DescriptorExtractor::create("ORB");

    std::vector<cv::KeyPoint> keyPointsA, keyPointsB;

    keyPointsA.push_back(cv::KeyPoint(0,0,5));
    keyPointsB.push_back(cv::KeyPoint(10,10,5));

    cv::Mat descriptorA, descriptorB;
    descriptor->compute(imgA, keyPointsA, descriptorA);
    descriptor->compute(imgB, keyPointsB, descriptorB);

    std::cout << "DescriptorA (" << descriptorA.rows << "," <<
                descriptorA.cols << ")" << std::endl;
    std::cout << "DescriptorB (" << descriptorB.rows << "," 
              << descriptorB.cols << ")" << std::endl;
    return 0;
}

The problem is that I am getting no data in the descriptor. What am I missing? Could you explain in more detail what are the params passed to the KeyPoint object? I am new to computer vision + OpenCV, so probably a better explanation (than OpenCV's documentation) could help.


Solution

  • You're trying to computer ORB on the points (0,0) and (10,10), but they are too close to the image border, so ORB can't compute descriptors in those locations. ORB (as well as the other binary descriptors) filters them out.

    EDIT: since you asked about usage, I'm editing the answer. You should pass the whole image. I use it as:

    Ptr<FeatureDetector> detector = FeatureDetector::create(detector_name);
    Ptr<DescriptorExtractor> descriptor = DescriptorExtractor::create(descriptor_name);
    
    detector->detect(imgK, kp);
    descriptor->compute(imgK, kp, desc);