问题是如果想要同时提取多个图像的描述符,openCV中的特征提取器的行为。 cv :: DescriptorExtractor提供了两个接口:
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
我在谈论允许传递一系列图像的第二个签名。我用以下最小例子测试了行为:
#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;
}
虽然上例中的版本1正确返回所有图像的描述符,但版本2没有 - 变量allDescriptors为空。但是,当我进入计算函数时,我可以观察到它在for循环中使用单个图像签名调用计算函数,但原始变量allDescriptors不受影响。我正在使用git存储库中最新的3.0版opencv。 DescriptorExtractor :: compute函数还有另一个问题。 SiftDescriptorExtractor继承自Feature2D,后者再次从DescriptorExtractor和FeatureDetector继承。 Feature2D仅覆盖
void DescriptorExtractor::compute(const Mat& image, vector<KeyPoint>& keypoints, Mat& descriptors) const
而不是接受图像序列的计算的重载。根据Scott Meyers,“Effective C ++”,第33项,这会影响计算的第二次重载。因此,如果我将指针从基类类型cv :: DescriptorExtractor *更改为cv :: xfeatures2d :: SiftDescriptorExtractor,则第二个重载不可用 - 编译器会抱怨没有带有正确签名的计算重载。我不确定这种行为是否有意。感谢您提供有关如何使DescriptorExtractor :: compute(...)适用于图像矢量的任何建议!