OpenCV 简短描述符少于关键点
OpenCV brief descriptors less than keypoints
我正在使用 OpenCV 检测特征和计算描述符。
我使用 FAST 进行特征检测:
cv::Ptr<cv::FeatureDetector> _detector = cv::FastFeatureDetector::create(_configuration.threshold,
_configuration.nonmaxSuppression);
对于描述符,我使用的是 BRIEF:
cv::Ptr<cv::DescriptorExtractor> _descriptor_extractor = cv::xfeatures2d::BriefDescriptorExtractor::create();
之后,我想根据他们的响应对关键点进行排序,并只存储一定数量的关键点:
typedef std::map<float,cv::KeyPoint,std::greater<float> > ResponseKeypointMap;
// keypoint buffer
std::vector<cv::KeyPoint> keypoints;
cv::Mat descriptors;
// detect keypoints
_detector->detect(rgb_image_, keypoints);
const int keypoints_size = keypoints.size();
if(!keypoints_size){
std::cerr << "warning: [PointDetector] found 0 keypoints!\n";
return;
}
ResponseKeypointMap keypoints_map;
for(int i=0; i < keypoints_size; ++i){
keypoints_map.insert(std::make_pair(keypoints[i].response,keypoints[i]));
}
int iterations = std::min(_configuration.max_keypoints_size,keypoints_size);
std::vector<cv::KeyPoint> filtered_keypoints;
filtered_keypoints.resize(iterations);
int k=0;
for(ResponseKeypointMap::iterator it = keypoints_map.begin();
it != keypoints_map.end();
++it){
filtered_keypoints[k] = it->second;
k++;
if(k>=iterations)
break;
}
std::cerr << "filtered keypoints size: " << filtered_keypoints.size() << std::endl;
_descriptor_extractor->compute(rgb_image_, filtered_keypoints, descriptors);
std::cerr << "Computed " << descriptors.rows << "x" << descriptors.cols << " descriptors" << std::endl;
我不知道为什么要为 DescriptorExtractor 提供 100 个关键点,但我收到了 55 个描述符。
如果你能向我解释发生了什么,我将不胜感激。
谢谢。
根据 OpenCV 文档 https://docs.opencv.org/2.4/modules/features2d/doc/common_interfaces_of_descriptor_extractors.html
DescriptorExtractor::compute(const Mat& image, vector& keypoints, Mat& descriptors)
...
keypoints – Input collection of keypoints. Keypoints for which a
descriptor cannot be computed are removed and the remaining ones may
be reordered. Sometimes new keypoints can be added, for example: SIFT
duplicates a keypoint with several dominant orientations (for each
orientation).
...
因此,在执行 compute 方法后,您的 filtered_keypoints 向量被更改,并且您有一对新的关键点和描述符,大小均为 55.
特别是,FAST 在每个 test-point 周围绘制了一个直径为 7 的环来确定它是否是关键点,但 BRIEF 在 test-point 周围使用了 256 个点。我不知道 BRIEF 使用方形区域还是圆形区域,但无论哪种方式,它都更大,因此 FAST 可能会找到离图像边界太近的关键点,BRIEF 无法计算描述。
我正在使用 OpenCV 检测特征和计算描述符。
我使用 FAST 进行特征检测:
cv::Ptr<cv::FeatureDetector> _detector = cv::FastFeatureDetector::create(_configuration.threshold,
_configuration.nonmaxSuppression);
对于描述符,我使用的是 BRIEF:
cv::Ptr<cv::DescriptorExtractor> _descriptor_extractor = cv::xfeatures2d::BriefDescriptorExtractor::create();
之后,我想根据他们的响应对关键点进行排序,并只存储一定数量的关键点:
typedef std::map<float,cv::KeyPoint,std::greater<float> > ResponseKeypointMap;
// keypoint buffer
std::vector<cv::KeyPoint> keypoints;
cv::Mat descriptors;
// detect keypoints
_detector->detect(rgb_image_, keypoints);
const int keypoints_size = keypoints.size();
if(!keypoints_size){
std::cerr << "warning: [PointDetector] found 0 keypoints!\n";
return;
}
ResponseKeypointMap keypoints_map;
for(int i=0; i < keypoints_size; ++i){
keypoints_map.insert(std::make_pair(keypoints[i].response,keypoints[i]));
}
int iterations = std::min(_configuration.max_keypoints_size,keypoints_size);
std::vector<cv::KeyPoint> filtered_keypoints;
filtered_keypoints.resize(iterations);
int k=0;
for(ResponseKeypointMap::iterator it = keypoints_map.begin();
it != keypoints_map.end();
++it){
filtered_keypoints[k] = it->second;
k++;
if(k>=iterations)
break;
}
std::cerr << "filtered keypoints size: " << filtered_keypoints.size() << std::endl;
_descriptor_extractor->compute(rgb_image_, filtered_keypoints, descriptors);
std::cerr << "Computed " << descriptors.rows << "x" << descriptors.cols << " descriptors" << std::endl;
我不知道为什么要为 DescriptorExtractor 提供 100 个关键点,但我收到了 55 个描述符。
如果你能向我解释发生了什么,我将不胜感激。
谢谢。
根据 OpenCV 文档 https://docs.opencv.org/2.4/modules/features2d/doc/common_interfaces_of_descriptor_extractors.html
DescriptorExtractor::compute(const Mat& image, vector& keypoints, Mat& descriptors)
...
keypoints – Input collection of keypoints. Keypoints for which a descriptor cannot be computed are removed and the remaining ones may be reordered. Sometimes new keypoints can be added, for example: SIFT duplicates a keypoint with several dominant orientations (for each orientation).
...
因此,在执行 compute 方法后,您的 filtered_keypoints 向量被更改,并且您有一对新的关键点和描述符,大小均为 55.
特别是,FAST 在每个 test-point 周围绘制了一个直径为 7 的环来确定它是否是关键点,但 BRIEF 在 test-point 周围使用了 256 个点。我不知道 BRIEF 使用方形区域还是圆形区域,但无论哪种方式,它都更大,因此 FAST 可能会找到离图像边界太近的关键点,BRIEF 无法计算描述。