OpenCV — используйте FLANN с дескрипторами ORB для сопоставления функций

Я использую 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

Как говорится Вот, 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);
}

2

Решение

Вы настраивали параметры FLANN?

Взято из http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_feature2d/py_matcher/py_matcher.html

Используя ORB, вы можете передать следующее. Закомментированные значения рекомендуются в соответствии с документами, но в некоторых случаях они не дают требуемых результатов. Другие значения работали нормально.

index_params = dict (алгоритм = 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));
5

Другие решения

Двоичные строки дескрипторов — ОРБ, КРАТКИЙ, БРИСК, ФРИК, АКАЗЕ и т. Д.

Дескрипторы с плавающей точкой — SIFT, SURF, GLOH и т. Д.


Сопоставление свойств двоичных дескрипторов может быть эффективно выполнено путем сравнения их Расстояние Хемминга в отличие от Евклидово расстояние используется для дескрипторов с плавающей точкой.

Для сравнения двоичных дескрипторов в OpenCV используйте FLANN + LSH индекс или же Грубая сила + расстояние Хэмминга.

http://answers.opencv.org/question/59996/flann-error-in-opencv-3/

По умолчанию FlannBasedMatcher работает как KDTreeIndex с нормой L2. Это причина, почему он хорошо работает с дескрипторами SIFT / SURF и бросает исключение для дескриптора ORB.

Двоичные функции и локальное хеширование (LSH)

Сравнение производительности между двоичными и плавающими дескрипторами

1

Я считаю, что есть ошибка в версии OpenCV3: Ошибка FLANN в OpenCV 3

Вам нужно конвертировать ваши дескрипторы в ‘CV_32F’.

0

Есть функция конвертации дескриптора в cv-32f. Пожалуйста, добавьте эту функцию, тогда приведенный выше код будет работать.

-1
По вопросам рекламы [email protected]