Roland Deschain
Roland Deschain

Reputation: 2850

OpenCV - FAST+BRIEF: How to draw keypoints with DrawMatchesFlags::DRAW_RICH_KEYPOINTS?

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

So, this is the code I have so far:

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");

The code so far works perfectly fine, however I don't get rich keypoints, but standard ones. If I understand correctly, this is because I need to somehow get the descriptor information to the keypoints first, right?

I have done the same implementation with SIFT, SURF and ORB before that, but there I use the computeanddetect function directly, which gives me keypoints, where I can draw with the DrawMatchesFlags::DRAW_RICH_KEYPOINTS flag.

Upvotes: 2

Views: 3238

Answers (1)

Grillteller
Grillteller

Reputation: 941

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

Yes, that is correct.

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

No, keypoints are detected by using different methods. You can use SIFT, FAST, HarrisDetector, SURF etc. only to detect keypoints at first. Then there are different methods to describe the detected keypoints (e.g. a 128-bit float vector descriptor for SIFT) and match them afterwards.
A keypoint in OpenCV can be described by the different attributes angle, size, octave and so on https://docs.opencv.org/3.4.2/d2/d29/classcv_1_1KeyPoint.html
For SIFT every KeyPoint attribute is filled with a number that can later be drawn in the DRAW_RICH_KEYPOINTS flag. For FAST only standard values for the attributes are assigned so that they keypoints can be drawn with the mentioned flag but the size, octave and angle do not vary. Thus, every drawn KeyPoint looks similar.

Here a small code sample as a proof (I only use the ->detect functions):

#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);


}   

Upvotes: 1

Related Questions