OpenCV (C ++) с использованием дескрипторов SIFT увеличивает количество обнаруженных функций? - PullRequest
0 голосов
/ 21 марта 2012

У меня немного запутанная ситуация при использовании дескрипторов SIFT из OpenCV.

Я пытаюсь протестировать различные методы расчета детектор признаков + дескриптор, поэтому я использую комбинацию интерфейсов cv::FeatureDetector и cv::DescriptorExtractor, которые позволяют мне просто переключаться между различными методами детектора и дескрипторами.

При вызове cv::DescriptorExtractor::compute(...) (вариант для отдельного изображения) в документации говорится, что количество ключевых точек, заданных алгоритму, возможно уменьшить , если невозможно вычислить их дескрипторы и я понимаю, как и почему это делается.

Но что со мной происходит, так это то, что число ключевых точек после вычислений дескриптора на самом деле увеличивается . Это явно так, и я не пытаюсь помешать этому случиться, я просто надеюсь объяснить, почему (просто интуитивное описание было бы здорово, хотя я ценю что-то большее).

У меня есть слои на слоях оберток вокруг фактического OpenCV, у которых нет никакого кода (просто устанавливаются некоторые локальные флаги, отличные от OpenCV), поэтому вот код OpenCV, который вызывается внизу всего этого:

cv::Ptr<cv::FeatureDetector> dect = cv::FeatureDetector::create("MSER");
cv::Mat input = cv::imread("someImg.ppm", 0);
std::vector<cv::KeyPoint> keypoints;
dect->detect(input, keypoints);

cv::Ptr<cv::DescriptorExtractor>deEx=cv::DescriptorCalculator::create("SIFT");

std::cout << "before computing, feats size " << keypoints.size() << std::endl;
// code to print out 10 features

cv::Mat desc;
deEx->compute(input, keypoints, desc);

std::cout << "after computing, feats size " << keypoints.size() << std::endl;
// code to print out 10 features

Я напечатал первые 10 ключевых точек непосредственно до и после вычислений дескриптора, поэтому вот несколько конкретных чисел в качестве примера:

before computing, feats size 379
feat[0]: 10.7584 39.9262 176.526 0 12.5396
feat[1]: 48.2209 207.904 275.091 0 11.1319
feat[2]: 160.894 313.781 170.278 0 9.63786
feat[3]: 166.061 239.115 158.33 0 19.5027
feat[4]: 150.043 233.088 171.887 0 11.9569
feat[5]: 262.323 322.173 188.103 0 8.65429
feat[6]: 189.501 183.462 177.396 0 12.3069
feat[7]: 218.135 253.027 171.763 0 123.069
feat[8]: 234.508 353.236 173.281 0 11.8375
feat[9]: 234.404 394.079 176.23 0 8.99652
after computing, feats size 463
feat[0]: 10.7584 39.9262 13.1313 0 12.5396
feat[1]: 48.2209 207.904 69.0472 0 11.1319
feat[2]: 48.2209 207.904 107.438 0 11.1319
feat[3]: 160.894 313.781 9.57937 0 9.63786
feat[4]: 166.061 239.115 166.144 0 19.5027
feat[5]: 150.043 233.088 78.8696 0 11.9569
feat[6]: 262.323 322.173 167.259 0 8.65429
feat[7]: 189.501 183.462 -1.49394 0 12.3069
feat[8]: 218.135 253.027 -117.067 3 123.069
feat[9]: 218.135 253.027 7.44055 3 123.069

Я вижу из этого примера, что исходные feat[1] и feat[7] охватывают до двух новых ключевых точек каждый, но я не вижу никакого логического объяснения для метода compute, чтобы сделать это: (*

Распечатка, которую я привел здесь, основана на использовании MSER для обнаружения ключевых точек, а затем на попытке вычислить дескрипторы SIFT , но те же увеличения в размере также происходит с обнаруженными ключевыми точками STAR , SURF и SIFT (т.е. DoG). Я не пытался изменить дескриптор SIFT на что-то другое, но если кто-то посчитает, что это актуально для вопроса, я попробую и отредактирую его в своем вопросе.

Ответы [ 3 ]

5 голосов
/ 21 марта 2012

Прежде всего, как вы можете видеть в документации cv::DescriptorExtractor::compute, принимайте аргумент std::vector<cv::Keypoints>, который в non const.Это означает, что этот вектор можно изменить с помощью cv::DescriptorExtractor::compute.На практике KeyPointsFilter::runByImageBorder и KeyPointsFilter::runByKeypointSize (две функции non-const) будут применены к вектору и удалят ключевую точку, для которой дескриптор не может быть вычислен.Повторное извлечение ключевых точек не будет выполнено.Вы должны опубликовать несколько строк кода, которые вы используете для дальнейшей диагностики.

-

Ну, я наконец-то нашел, где возникает проблема: cv::SiftDescriptorExtractor::compute вызовы методов SIFT::operator(), которые (пере) вычисляют ориентацию объектов, а также дублируют точки с несколькими доминирующими ориентациями.Решением может быть изменение descriptorParams.recalculateAngles на false.

2 голосов
/ 21 марта 2012

Похоже, это связано с тем, что OpenCV использует реализацию SIFT Роба Хесса, которая иногда дублирует ключевые точки с более чем одной доминирующей ориентацией.

Оглядываясь на сообщения об ошибках, обнаруженных OpenCV, добились цели, проблема была сообщена здесь .

Это не ошибка, поведение не было исправлено в более новых версиях, а просто задокументировано. Поскольку я обязан используемой прямо сейчас версии OpenCV (v2.1), мне не пришло в голову взглянуть на более новую документацию , чтобы узнать о дополнительном поведении, поскольку поведение, описанное в старой имело смысл для меня.

0 голосов
/ 02 марта 2013

Это не ошибка, но по замыслу:

SIFT возвращает несколько точек интереса в одном и том же месте с разными ориентациями, если явно не существует одной доминирующей ориентации. Обычно оценивается до трех (в зависимости от фактического участка изображения) ориентации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...