OpenCV - 使用带有 ORB 描述符的 FLANN 来匹配特征
OpenCV - Use FLANN with ORB descriptors to match features
我正在使用 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);
}
你调整FLANN参数了吗?
取自http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_feature2d/py_matcher/py_matcher.html
While using ORB, you can pass the following. The commented values are recommended as per the docs, but it didn’t provide required results in some cases. Other values worked fine.:
index_params= dict(algorithm = FLANN_INDEX_LSH,
table_number = 6, # 12
key_size = 12, # 20
multi_probe_level = 1) #2
也许您可以将其转换为 C++ api?
根据评论,C++方式是:
cv::FlannBasedMatcher matcher = cv::FlannBasedMatcher(cv::makePtr<cv::flann::LshIndexParams>(12, 20, 2));
我认为 OpenCV3 版本中存在错误:
您需要将描述符转换为 'CV_32F'。
有一个函数将 desxriptor 转换为 cv-32f。请添加此功能然后上面的代码将起作用。
二进制字符串描述符 - ORB、BRIEF、BRISK、FREAK、AKAZE 等
浮点描述符 - SIFT、SURF、GLOH 等
二进制描述符的特征匹配可以通过比较它们的汉明距离而不是用于浮点描述符的欧几里得距离来有效地完成.
要比较 OpenCV 中的二进制描述符,请使用 FLANN + LSH 索引 或 蛮力 + 汉明距离。
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
我正在使用 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);
}
你调整FLANN参数了吗?
取自http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_feature2d/py_matcher/py_matcher.html
While using ORB, you can pass the following. The commented values are recommended as per the docs, but it didn’t provide required results in some cases. Other values worked fine.:
index_params= dict(algorithm = FLANN_INDEX_LSH, table_number = 6, # 12 key_size = 12, # 20 multi_probe_level = 1) #2
也许您可以将其转换为 C++ api?
根据评论,C++方式是:
cv::FlannBasedMatcher matcher = cv::FlannBasedMatcher(cv::makePtr<cv::flann::LshIndexParams>(12, 20, 2));
我认为 OpenCV3 版本中存在错误:
您需要将描述符转换为 'CV_32F'。
有一个函数将 desxriptor 转换为 cv-32f。请添加此功能然后上面的代码将起作用。
二进制字符串描述符 - ORB、BRIEF、BRISK、FREAK、AKAZE 等
浮点描述符 - SIFT、SURF、GLOH 等
二进制描述符的特征匹配可以通过比较它们的汉明距离而不是用于浮点描述符的欧几里得距离来有效地完成.
要比较 OpenCV 中的二进制描述符,请使用 FLANN + LSH 索引 或 蛮力 + 汉明距离。
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