特征点的生成和匹配
两张不同视角,同一相机拍摄的图片
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui.hpp> // 添加此行
using namespace std;
using namespace cv; // 添加此行
int main(int argc, char** argv)
{
namedWindow("show", WINDOW_NORMAL);
resizeWindow("show", 800, 600);
// read two images
Mat img1 = imread("/home/ubuntu/Desktop/features point/1.jpg.png");
Mat img2 = imread("/home/ubuntu/Desktop/features point/2.jpg.png");
// 检查图像是否成功加载
if (img1.empty() || img2.empty())
{
cout << "Error: Failed to load image(s)!" << endl;
return -1;
}
// using gray image to compute
Mat gray1, gray2;
cvtColor(img1, gray1, COLOR_BGR2GRAY);
cvtColor(img2, gray2, COLOR_BGR2GRAY);
// create orb detector
Ptr<ORB> orb = ORB::create();
// create the container of Key points
vector<KeyPoint> feature_points1, feature_points2;
// do Orient_FAST detect Keypoint
orb->detect(gray1, feature_points1);
orb->detect(gray2, feature_points2);
// compute the descriptors
Mat descriptor1, descriptor2;
orb->compute(gray1, feature_points1, descriptor1);
orb->compute(gray2, feature_points2, descriptor2);
// do matching
// create Matcher
BFMatcher matcher(NORM_HAMMING); // O(N^2)
vector<DMatch> pairs;
matcher.match(descriptor1, descriptor2, pairs);
// draw the matched pairs and show
Mat canvas;
drawMatches(img1, feature_points1, img2, feature_points2, pairs, canvas);
imshow("show", canvas);
waitKey(0);
// You can also filter the match to generate
vector<DMatch> good;
double min_dist = 100000;
// compute the minimum of the distance
for (const DMatch& m : pairs)
{
if (m.distance < min_dist) min_dist = m.distance;
}
// filter
for (const DMatch& m : pairs)
{
if (m.distance < max(min_dist * 2, 30.))
{
good.push_back(m);
}
}
drawMatches(img1, feature_points1, img2, feature_points2, good, canvas);
imwrite("../good_match.jpg", canvas);
imshow("show", canvas);
waitKey(0);
// draw the keypoint
drawKeypoints(img1, feature_points1, canvas, Scalar::all(-1), DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
imwrite("../keypoints.jpg", canvas);
imshow("show", canvas);
waitKey(0);
// 释放窗口资源
destroyAllWindows();
return 0;
}
结果图