[opencv]KAZE、AKAZE特征检测、匹配与对象查找
AkAZE是KAZE的加速版
与SIFT,SUFR比较:
1.更加稳定
2.非线性尺度空间
3.AKAZE速度更加快
4.比较新的算法,只有Opencv新的版本才可以用
AKAZE局部匹配介绍
1.AOS构造尺度空间
2.Hessian矩阵特征点
3.方向指定基于一阶微分图像
4.描述子生成
特征点查找和绘制:把surf中的surf改成KAZE或AKAZE即可
#include <opencv2/opencv.hpp> #include <opencv2/features2d.hpp> #include <iostream> using namespace cv; using namespace cv::features2d; using namespace std; int Akaze feature detection(){ Mat src = imread("test.jpg", IMREAD_GRAYSCALE); if (src.empty()) { printf("could not load image...\n"); return -1; } namedWindow("input image", CV_WINDOW_AUTOSIZE); imshow("input image", src); // AKAZE特征点检测 Ptr<AKAZE> detector = AKAZE::create();//创建一个AKAZE类对象并初始化 vector<KeyPoint> keypoints; detector->detect(src, keypoints, Mat());//找Mat src = imread("test.jpg", IMREAD_GRAYSCALE); if (src.empty()) { printf("could not load image...\n"); return -1; } namedWindow("input image", CV_WINDOW_AUTOSIZE); imshow("input image", src); // AKAZE特征点检测 Ptr<AKAZE> detector = AKAZE::create();//创建一个AKAZE类对象并初始化 vector<KeyPoint> keypoints; detector->detect(src, keypoints, Mat());//找出关键点 // 绘制关键点 Mat keypoint_img; drawKeypoints(src, keypoints, keypoint_img, Scalar::all(-1), DrawMatchesFlags::DEFAULT); imshow("KeyPoints Image", keypoint_img); waitKey(0); return 0; }
匹配:
int featurematching{ Mat img1 = imread("/home/leoxae/KeekoRobot/TestPic/qrcodetest/13.png"); Mat img2 = imread("/home/leoxae/KeekoRobot/TestPic/qrcodetest/13.png"); imshow("box image", img1); imshow("scene image", img2); // extract akaze features Ptr<AKAZE> detector = AKAZE::create(); vector<KeyPoint> keypoints_obj; vector<KeyPoint> keypoints_scene; Mat descriptor_obj, descriptor_scene; detector->detectAndCompute(img1, Mat(), keypoints_obj, descriptor_obj); detector->detectAndCompute(img2, Mat(), keypoints_scene, descriptor_scene); // matching FlannBasedMatcher matcher(new flann::LshIndexParams(20, 10, 2)); //FlannBasedMatcher matcher; vector<DMatch> matches; matcher.match(descriptor_obj, descriptor_scene, matches); // draw matches(key points) Mat akazeMatchesImg; /* drawMatches(img1, keypoints_obj, img2, keypoints_scene, matches, akazeMatchesImg); imshow("akaze match result", akazeMatchesImg);*/ vector<DMatch> goodMatches; double minDist = 100000, maxDist = 0; for (int i = 0; i < descriptor_obj.rows; i++) { double dist = matches[i].distance; if (dist < minDist) { minDist = dist; } if (dist > maxDist) { maxDist = dist; } } printf("min distance : %f", minDist); for (int i = 0; i < descriptor_obj.rows; i++) { double dist = matches[i].distance; if (dist < max( 1.5*minDist, 0.02)) { goodMatches.push_back(matches[i]); } } drawMatches(img1, keypoints_obj, img2, keypoints_scene, goodMatches, akazeMatchesImg, Scalar::all(-1), Scalar::all(-1), vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS); imshow("good match result", akazeMatchesImg); waitKey(0); }
Talk is cheap. Show me the code