Установите количество ключевых точек в Android OpenCV

Я пытаюсь запустить обнаружение функций на изображении, используя некоторые встроенные детекторы функций OpenCV. Однако я хочу определить только лучшие/лучшие n функции, присутствующие в изображении (скажем, 30 для этого примера). У меня уже есть код, который находит функции и затем использует их для идентификации этого объекта на других изображениях, но я не могу понять, как ограничить количество найденных ключевых точек. Я инициализирую различные детекторы/экстракторы/сопоставители, как показано ниже:

private final FeatureDetector mFeatureDetector = FeatureDetector.create(FeatureDetector.ORB);
private final DescriptorExtractor mDescriptorExtractor = descriptorExtractor.create(DescriptorExtractor.ORB);
private final DescriptorMatcher mDescriptorMatcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMINGLUT);

Я пытался найти решение уже на SO, но единственные решения, которые я могу найти, не для версии OpenCV для Android. Попытка использовать аналогичные методы для этих решений также не сработала.

Единственный метод, который, как мне кажется, может сработать, — это просто взять первые 30 признаков, но я не думаю, что это сработает хорошо, поскольку все они могут быть сгруппированы в одной части изображения. Поэтому мне было интересно, знает ли кто-нибудь, как можно выбрать 30 лучших функций (если они действительно могут). Меня не волнует, для какого алгоритма обнаружения функций предназначено решение (MSER, ORB, SIFT, SURF, STAR, GFTT и т. д.).

Я также требую, чтобы каждый раз обнаруживалось ровно 30 функций, поэтому игра с чувствительностью до тех пор, пока она не станет «примерно правильной», не вариант.

EDIT: причина необходимости найти ровно 30 функций заключается в том, что я собираюсь использовать их для обучения своего детектора. Идея состоит в том, что я получу 30 признаков из каждого набора обучающих изображений, а затем использую результат, чтобы снова найти объект в сцене. Поскольку тренировочные изображения будут крупным планом объекта, не имеет значения, что функции не будут сгруппированы в одной части изображения.


person TheOmegaPostulate    schedule 17.12.2014    source источник
comment
В каждом алгоритме нет nFeatures (см. конструктор SURF в src), как в github.com/Itseez/opencv_contrib/blob/master/modules/. Обертки Java не предусмотрены для каждого алгоритма, поскольку они не бесплатны. У нас есть только общий create. Кроме того, даже если вы получите 30 лучших функций, нет гарантии, что они не будут сгруппированы в одной части изображения. Можете ли вы дать больше ясности о необходимости ограничения функций? Поможет ли knnMatch или radiusMatch?   -  person kiranpradeep    schedule 18.12.2014
comment
Я обновил свой вопрос, указав, почему мне нужно ограничивать функции (я тренирую свой детектор таким образом, что ему требуется постоянное количество функций). К сожалению, я не думаю, что knnMatch или radiusMatch помогут, но спасибо за мысль. Вы знаете, как был реализован алгоритм nFeatures?   -  person TheOmegaPostulate    schedule 19.12.2014
comment
Я не уверен, правильно ли я понял ваш вопрос! В C++ функциональные точки (я знаю это из SURF) сортируются по отклику используемого фильтра. Если это не в Android, вы можете сделать это самостоятельно, потому что каждая ключевая точка, которую вы обнаруживаете, имеет значение члена ответа с плавающей запятой. Итак, первые 30 ключевых точек в списке должны быть ключевыми точками с наибольшим откликом. Они не сгруппированы в части изображения естественным образом!   -  person PeterNL    schedule 19.12.2014
comment
Спасибо за ваш ответ, это то, что я надеялся, что смогу сделать! Однако каждая ключевая точка SURF по умолчанию является 64-битным вектором, и я не знаю, какая часть этого вектора является значением члена ответа с плавающей запятой. Вы знаете, что это такое или как я могу узнать?   -  person TheOmegaPostulate    schedule 22.12.2014


Ответы (1)


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

Моя переменная ключевых точек:

private final MatOfKeyPoint mTargetKeypoints = new MatOfKeyPoint();

После того, как он был «заполнен» функциями (кажется, что это останавливается после 500), отдельные функции могут быть извлечены путем преобразования их в массив (где каждый элемент массива является функцией.

mTargetKeypoints.toArray()[0]; //NOTE: Not actual code, used in a print statement

Когда я печатаю приведенное выше, результат:

KeyPoint [pt={82.0, 232.0}, размер=31.0, угол=267.77094, ответ=0.0041551706, октава=0, class_id=-1]

Затем индивидуальную информацию можно извлечь с помощью встроенных функций Keypoint, например:

mTargetKeypoints.toArray()[0].pt.x //Printing outputs x location of feature.
mTargetKeypoints.toArray()[0].response // Printing outputs response of feature. 

Этот вопрос SO указывает, что ответ показывает, насколько хороша ключевая точка. Таким образом, здесь относительно просто выбрать 30 лучших функций для использования.

person TheOmegaPostulate    schedule 22.12.2014