暂时记录一下
OpenCV版本:
#include<iostream>
#include<opencv2/opencv.hpp>
#include<opencv2/core.hpp>
#include<opencv2/features2d.hpp>
#include <opencv2/xfeatures2d/nonfree.hpp>
using namespace std;
using namespace cv;
using namespace cv::xfeatures2d;
int main(int argc, char* argv[]) {
Mat img_object = imread("a.jpg", IMREAD_GRAYSCALE);
Mat img_scene = imread("b.jpg", IMREAD_GRAYSCALE);
Ptr<SIFT> detector = SIFT::create(argc > 1 ? atoi(argv[1]) : 400);
if (img_object.empty() || img_scene.empty()) {
cout << "Could not open or find the image!\n" << endl;
return -1;
}
std::vector<KeyPoint> keypoints_object, keypoints_scene;
Mat descriptors_object, descriptors_scene;
detector->detectAndCompute(img_object, noArray(), keypoints_object, descriptors_object);
detector->detectAndCompute(img_scene, noArray(), keypoints_scene, descriptors_scene);
//-- Step 2: Matching descriptor vectors with a FLANN based matcher
// Since SURF is a floating-point descriptor NORM_L2 is used
Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create(DescriptorMatcher::FLANNBASED);
std::vector< std::vector<DMatch> > knn_matches;
matcher->knnMatch(descriptors_object, descriptors_scene, knn_matches, 2);
//-- Filter matches using the Lowe's ratio test
const float ratio_thresh = 0.85f;
std::vector<DMatch> good_matches;
for (size_t i = 0; i < knn_matches.size(); i++)
{
if (knn_matches[i][0].distance < ratio_thresh * knn_matches[i][1].distance)
{
good_matches.push_back(knn_matches[i][0]);
}
}
img_object = imread("a.jpg");
img_scene = imread("b.jpg");
for (auto& k : keypoints_object) {
circle(img_object, k.pt, k.size, CV_RGB(255, 0, 0));
}
for (auto& k : keypoints_scene) {
circle(img_scene, k.pt, k.size, CV_RGB(0, 255, 0));
}
//-- Draw matches
Mat img_matches;
drawMatches(img_object, keypoints_object, img_scene, keypoints_scene, good_matches, img_matches, Scalar::all(-1),
Scalar::all(-1), std::vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);
//-- Localize the object
std::vector<Point2f> obj;
std::vector<Point2f> scene;
for (size_t i = 0; i < good_matches.size(); i++)
{
//-- Get the keypoints from the good matches
obj.push_back(keypoints_object[good_matches[i].queryIdx].pt);
scene.push_back(keypoints_scene[good_matches[i].trainIdx].pt);
}
/*
Mat H = findHomography(obj, scene, RANSAC);
//-- Get the corners from the image_1 ( the object to be "detected" )
std::vector<Point2f> obj_corners(4);
obj_corners[0] = Point2f(0, 0);
obj_corners[1] = Point2f((float)img_object.cols, 0);
obj_corners[2] = Point2f((float)img_object.cols, (float)img_object.rows);
obj_corners[3] = Point2f(0, (float)img_object.rows);
std::vector<Point2f> scene_corners(4);
perspectiveTransform(obj_corners, scene_corners, H);
//-- Draw lines between the corners (the mapped object in the scene - image_2 )
line(img_matches, scene_corners[0] + Point2f((float)img_object.cols, 0),
scene_corners[1] + Point2f((float)img_object.cols, 0), Scalar(0, 255, 0), 4);
line(img_matches, scene_corners[1] + Point2f((float)img_object.cols, 0),
scene_corners[2] + Point2f((float)img_object.cols, 0), Scalar(0, 255, 0), 4);
line(img_matches, scene_corners[2] + Point2f((float)img_object.cols, 0),
scene_corners[3] + Point2f((float)img_object.cols, 0), Scalar(0, 255, 0), 4);
line(img_matches, scene_corners[3] + Point2f((float)img_object.cols, 0),
scene_corners[0] + Point2f((float)img_object.cols, 0), Scalar(0, 255, 0), 4);
*/
//-- Show detected matches
imshow("Good Matches & Object detection", img_matches);
waitKey();
return 0;
}
如果要用SURF,改这行代码即可:
//Ptr<SIFT> detector = SIFT::create(argc > 1 ? atoi(argv[1]) : 400);
Ptr<SURF> detector = SURF::create(argc > 1 ? atoi(argv[1]) : 400);
SURF是受专利保护的,所以编译OpenCV的时候需要把Contrib包一起编译,还要勾选OPENCV_ENABLE_NONFREE
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210314181942339.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,tex
_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MTY2NTIyNQ==,size_16,color_FFFFFF,t_70#pic_center)
SURF比较慢,精度怎样不做比较。
VLFeat 的SIFT版本据说比OpenCV好。
代码下载来后,为Visual Studio 2019建立工程文件 libvlfeat_sift.vcxproj 和vl目录同一级。
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration&g