我正在使用OpenCV 3.2
我正在尝试使用FLANN以比蛮力更快的方式匹配要素描述符。
// Ratio to the second neighbor to consider a good match.
#define RATIO 0.75
void matchFeatures(const cv::Mat &query, const cv::Mat &target,
std::vector<cv::DMatch> &goodMatches) {
std::vector<std::vector<cv::DMatch>> matches;
cv::Ptr<cv::FlannBasedMatcher> matcher = cv::FlannBasedMatcher::create();
// Find 2 best matches for each descriptor to make later the second neighbor test.
matcher->knnMatch(query, target, matches, 2);
// Second neighbor ratio test.
for (unsigned int i = 0; i < matches.size(); ++i) {
if (matches[i][0].distance < matches[i][1].distance * RATIO)
goodMatches.push_back(matches[i][0]);
}
}
此代码使用SURF和SIFT描述符,但不使用ORB。
OpenCV Error: Unsupported format or combination of formats (type=0) in buildIndex
正如here所述,FLANN需要描述符为CV_32F类型,因此我们需要转换它们。
if (query.type() != CV_32F) query.convertTo(query, CV_32F);
if (target.type() != CV_32F) target.convertTo(target, CV_32F);
但是,这个假定的修复程序在convertTo
函数中返回了另一个错误。
OpenCV Error: Assertion failed (!fixedType() || ((Mat*)obj)->type() == mtype) in create
此断言位于opencv/modules/core/src/matrix.cpp
文件第2277行。
发生了什么事?
复制问题的代码。
#include <opencv2/opencv.hpp>
int main(int argc, char **argv) {
// Read both images.
cv::Mat image1 = cv::imread(argv[1], cv::IMREAD_GRAYSCALE);
if (image1.empty()) {
std::cerr << "Couldn't read image in " << argv[1] << std::endl;
return 1;
}
cv::Mat image2 = cv::imread(argv[2], cv::IMREAD_GRAYSCALE);
if (image2.empty()) {
std::cerr << "Couldn't read image in " << argv[2] << std::endl;
return 1;
}
// Detect the keyPoints and compute its descriptors using ORB Detector.
std::vector<cv::KeyPoint> keyPoints1, keyPoints2;
cv::Mat descriptors1, descriptors2;
cv::Ptr<cv::ORB> detector = cv::ORB::create();
detector->detectAndCompute(image1, cv::Mat(), keyPoints1, descriptors1);
detector->detectAndCompute(image2, cv::Mat(), keyPoints2, descriptors2);
// Match features.
std::vector<cv::DMatch> matches;
matchFeatures(descriptors1, descriptors2, matches);
// Draw matches.
cv::Mat image_matches;
cv::drawMatches(image1, keyPoints1, image2, keyPoints2, matches, image_matches);
cv::imshow("Matches", image_matches);
}
答案 0 :(得分:2)
二进制字符串描述符-ORB,BRIEF,BRISK,FREAK,AKAZE等。
浮点描述符-SIFT,SURF,GLOH等。
要在OpenCV中比较二进制描述符,请使用 FLANN + LSH索引或 Brute Force + Hamming距离。
http://answers.opencv.org/question/59996/flann-error-in-opencv-3/
默认情况下,FlannBasedMatcher用作具有L2规范的KDTreeIndex。这就是为什么它可以与SIFT / SURF描述符以及throws an exception一起用于ORB描述符的原因。
Binary features and Locality Sensitive Hashing (LSH)
Performance comparison between binary and floating-point descriptors
答案 1 :(得分:0)
我相信OpenCV3版本中存在一个错误:FLANN error in OpenCV 3
您需要将描述符转换为'CV_32F'。
答案 2 :(得分:-1)
有一个功能将desxriptor转换为cv-32f。请添加此功能,然后上面的代码将起作用。