Reputation: 2850
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
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