Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Why does cv::DescriptorExtractor::compute return empty descriptors for a std::vector<cv::mat>?

First, I already asked this question on Stackoverflow but I did not find a solution so far or it might be a bug. Therefor I repeat my question here: The problem is the behaviour of feature extractors in openCV if one wants to extract descriptors of several images at the same time. The cv::DescriptorExtractor offers two interfaces for that:

void DescriptorExtractor::compute(const Mat& image, vector<KeyPoint>& keypoints, Mat& descriptors) const
void DescriptorExtractor::compute(const vector<Mat>& images, vector<vector<KeyPoint>>& keypoints, vector<Mat>& descriptors) const

I am talking about the second signature which allows to pass a sequence of images. I tested the behaviour with the following minimal example:

#include"opencv2\opencv.hpp"
#include "opencv2\xfeatures2d\nonfree.hpp"

int main(){

    //Read image
    cv::Mat img = cv::imread("./sample.png");
    //Create vector of images
    std::vector<cv::Mat> imageSequence(10, img);
    //Create SIFT detector and extractor
    cv::FeatureDetector* detector = new cv::xfeatures2d::SiftFeatureDetector();
    cv::DescriptorExtractor* extractor = new cv::xfeatures2d::SiftDescriptorExtractor();
    //Keypoints
    std::vector<std::vector<cv::KeyPoint>> keypoints;
    //Compute keypoints
    detector->detect(imageSequence, keypoints);
    //This vector should contain all descriptors
    std::vector<cv::Mat> allDescriptors;
    //Version 1: Using a for loop and the single image signature of DescriptorExtractor::compute works.
    for (int i = 0; i < imageSequence.size(); ++i){
        cv::Mat descriptors;
        //This compute(...) works
        extractor->compute(imageSequence.at(i), keypoints.at(i), descriptors);
        allDescriptors.push_back(descriptors);
    }

    allDescriptors.clear();
    //Version 2: Using the interface for the computation of descriptors for std::vector<cv::Mat> fails
    extractor->compute(imageSequence, keypoints, allDescriptors);

    return 0;
}

While Version 1 in the example above returns the descriptors for all images correctly, the Version 2 does not - the variable allDescriptors is empty. However, when I step into the compute function I can observe that it calls the compute function with the single image signature in a for loop but the original variable allDescriptors is unaffected. I am working with the latest 3.0 version of opencv from the git repository. It seems that the computed descriptors are computed but not stored in allDescriptors and the result is lost after return.