OpenCV — FAST + BRIEF: как рисовать ключевые точки с помощью DrawMatchesFlags::DRAW_RICH_KEYPOINTS?

Мне нужно реализовать детектор функций, используя FAST + BRIEF (это ручная реализация ORB, если я правильно понимаю).

Итак, это код, который у меня есть до сих пор:

printf("Calculating FAST+BRIEF features...\n");

Ptr<FastFeatureDetector> FASTdetector = FastFeatureDetector::create();
Ptr<BriefDescriptorExtractor> BRIEFdescriptor = BriefDescriptorExtractor::create();
std::vector<cv::KeyPoint> FASTkeypoints_1, FASTkeypoints_2, FASTkeypoints_3;
Mat BRIEFdescriptors_1, BRIEFdescriptors_2, BRIEFdescriptors_3;

FASTdetector->detect(left08, FASTkeypoints_1);
FASTdetector->detect(right08, FASTkeypoints_2);
FASTdetector->detect(left10, FASTkeypoints_3);

BRIEFdescriptor->compute(left08, FASTkeypoints_1, BRIEFdescriptors_1);
BRIEFdescriptor->compute(right08, FASTkeypoints_2, BRIEFdescriptors_2);
BRIEFdescriptor->compute(left10, FASTkeypoints_3, BRIEFdescriptors_3);

Mat FAST_left08, FAST_right08, FAST_left10;

drawKeypoints(left08, FASTkeypoints_1, FAST_left08, FASTBRIEFfeatcol_YELLOW, DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
imwrite("../Results/FASTBRIEF_left08.png", FAST_left08);
drawKeypoints(right08, FASTkeypoints_2, FAST_right08, FASTBRIEFfeatcol_YELLOW, DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
imwrite("../Results/FASTBRIEF_right08.png", FAST_right08);
drawKeypoints(left10, FASTkeypoints_3, FAST_left10, FASTBRIEFfeatcol_YELLOW, DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
imwrite("../Results/FASTBRIEF_left10.png", FAST_left10);
printf("FAST+BRIEF done. \n");

Код пока работает отлично, однако я получаю не богатые ключевые точки, а стандартные. Если я правильно понимаю, это потому, что мне нужно сначала каким-то образом получить информацию о дескрипторе ключевых точек, верно?

Я сделал ту же реализацию с SIFT, SURF и ORB до этого, но там я использую функцию computeanddetect напрямую, которая дает мне ключевые точки, где я могу рисовать с помощью флага DrawMatchesFlags::DRAW_RICH_KEYPOINTS.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
1 537
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

I have to implement a feature detector using FAST+BRIEF (which is the manual implementation of ORB if I understand correctly).

Да, это правильно.

If I understand correctly, this is because I need to somehow get the descriptor information to the keypoints first, right?

Нет, ключевые точки обнаруживаются разными методами. Сначала вы можете использовать SIFT, FAST, HarrisDetector, SURF и т. д. Ключевые точки только для обнаружения. Затем существуют различные методы для описания обнаруженных ключевых точек (например, 128-битный векторный дескриптор с плавающей запятой для SIFT) и последующего их сопоставления.
Ключевая точка в OpenCV может быть описана различными атрибутами: углом, размером, октавой и т. д. https://docs.opencv.org/3.4.2/d2/d29/classcv_1_1KeyPoint.html
Для SIFT каждый атрибут KeyPoint заполняется числом, которое позже можно нарисовать во флаге DRAW_RICH_KEYPOINTS. Для FAST назначаются только стандартные значения для атрибутов, так что их ключевые точки можно рисовать с указанным флажком, но размер, октава и угол не изменяются. Таким образом, каждая нарисованная KeyPoint выглядит одинаково.

Вот небольшой пример кода в качестве доказательства (я использую только функции ->detect):

#include <iostream>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/xfeatures2d/nonfree.hpp>  

int main(int argc, char** argv)
{

    // Load image
    cv::Mat img = cv::imread("MT189.jpg", CV_LOAD_IMAGE_GRAYSCALE);
    if (!img.data) {
        std::cout << "Error reading image" << std::endl;
        return EXIT_FAILURE;
    }
    cv::Mat output;

    // Detect FAST keypoints
    std::vector<cv::KeyPoint> keypoints_fast, keypoints_sift;
    cv::Ptr<cv::FastFeatureDetector> fast = cv::FastFeatureDetector::create();
    fast->detect(img, keypoints_fast);
    for (size_t i = 0; i < 100; ++i) {
        std::cout << "FAST Keypoint #:" << i;
        std::cout << " Size " << keypoints_fast[i].size << " Angle " << keypoints_fast[i].angle << " Response " << keypoints_fast[i].response << " Octave " << keypoints_fast[i].octave << std::endl;
    }

    // Detect SIFT keypoints
    cv::Ptr<cv::xfeatures2d::SiftFeatureDetector> sift = cv::xfeatures2d::SiftFeatureDetector::create();
    sift->detect(img, keypoints_sift);

    for (size_t i = 0; i < 100; ++i) {
        std::cout << "SIFT Keypoint #:" << i;
        std::cout << " Size " << keypoints_sift[i].size << " Angle " << keypoints_sift[i].angle << " Response " << keypoints_sift[i].response << " Octave " << keypoints_sift[i].octave << std::endl;
    }

    // Draw SIFT keypoints
    cv::drawKeypoints(img, keypoints_sift, output, cv::Scalar::all(-1), cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
    cv::imshow("Output", output);
    cv::waitKey(0);


}   

Другие вопросы по теме