文章目录 一、KAZE简介二、代码演示特征检测效果对比演示匹配
一、KAZE简介
ECCV2012中出现了一种比SIFT更稳定的特征检测算法KAZE ([1])。KAZE的取名是为了纪念尺度空间分析的开创者—日本学者Iijima。KAZE是日语‘风’的谐音,寓意是就像风的形成是空气在空间中非线性的流动过程一样,KAZE特征检测是在图像域中进行非线性扩散处理的过程。
关于KAZE算法详情讲解:https://blog.csdn.net/chenyusiyuan/article/details/8715129
传统的SIFT、SURF等特征检测算法都是基于线性的高斯金字塔进行多尺度分解来消除噪声和提取显著特征点。但高斯分解是牺牲了局部精度为代价的,容易造成边界模糊和细节丢失。
非线性的尺度分解有望解决这种问题,但传统方法基于正向欧拉法(forward Euler scheme)求解非线性扩散(Non-linear diffusion)方程时迭代收敛的步长太短,耗时长、计算复杂度高。由此,KAZE算法的作者提出采用 加性算子分裂算法(Additive Operator Splitting, AOS)来进行非线性扩散滤波,可以采用任意步长来构造稳定的非线性尺度空间。
关于图像特征集算法介绍:请查看
下面为AKAZE局部匹配介绍(KAZE的加速版)
整个算法流程:香港vps
非线性扩散滤波与尺度空间构建:(Perona-Malik扩散方程)–>(AOS算法)Hessian矩阵特征点检测特征检测与描述子生成:(特征点主方向:一阶微分图像)–>(构造特征描述向量) 二、代码演示
头文件 image_feature_all.h:声明类与公共函数
#pragma once#include <opencv2/opencv.hpp>#include <iostream>#include <opencv2/xfeatures2d.hpp> //新增引入库using namespace cv;using namespace std;class ImageFeature {public:void kaze_akaze_demo(Mat& image, Mat& image2);void akazeMatch_demo(Mat& image, Mat& image2);};
主函数main.cpp调用该类的公共成员函数
#include “image_feature_all.h”int main(int argc, char** argv) {const char* img_path = “D:\\Desktop\\match_dst.jpg”;const char* img_path2 = “D:\\Desktop\\match_raw.jpg”;Mat image = imread(img_path, IMREAD_GRAYSCALE);Mat image2 = imread(img_path2, IMREAD_GRAYSCALE);if (image.empty() || image2.empty()) {cout << “图像数据为空,读取文件失败!” << endl;}ImageFeature imgfeature;imgfeature.kaze_akaze_demo(image, image2);imgfeature.akazeMatch_demo(image, image2);waitKey(0);destroyAllWindows();return 0;} 特征检测效果对比 void ImageFeature::kaze_akaze_demo(Mat& image, Mat& image2) {// KAZE 检测Ptr<KAZE> kaze_detector = KAZE::create();vector<KeyPoint> kaze_keypoints;double t0 = getTickCount();kaze_detector->detect(image2, kaze_keypoints, Mat());double t1 = getTickCount();cout << ” kaze_keypoints:” << kaze_keypoints.size() << endl;cout << ” KAZE cost time:” << ((t1 – t0) / getTickFrequency()) << endl;Mat kaze_Img;drawKeypoints(image2, kaze_keypoints, kaze_Img, Scalar::all(-1), DrawMatchesFlags::DEFAULT);imshow(“kaze_Img”, kaze_Img);// AKAZE 检测Ptr<AKAZE> akaze_detector = AKAZE::create();vector<KeyPoint> akaze_keypoints;double t00 = getTickCount();akaze_detector->detect(image2, akaze_keypoints, Mat());double t11 = getTickCount();cout << “akaze_keypoints:” << akaze_keypoints.size() << endl;cout << “AKAZE cost time:” << ((t11 – t00) / getTickFrequency()) << endl;Mat akaze_Img;Mat image2_copy = image2.clone();drawKeypoints(image2_copy, akaze_keypoints, akaze_Img, Scalar::all(-1), DrawMatchesFlags::DEFAULT);imshow(“akaze_Img”, akaze_Img);}
快了大约6倍,但是检测的特征好像少了不少。
kaze_keypoints:1238
KAZE cost time:0.209193
akaze_keypoints:977
AKAZE cost time:0.0335966
演示匹配 void ImageFeature::akazeMatch_demo(Mat& image, Mat& image2) {// AKAZE feature detectPtr<AKAZE> akaze_detector = AKAZE::create();vector<KeyPoint> keypoints_obj,keypoints_scens;Mat descriptor_obj, descriptor_scens;double t00 = getTickCount();akaze_detector->detectAndCompute(image, Mat(), keypoints_obj, descriptor_obj);akaze_detector->detectAndCompute(image2, Mat(), keypoints_scens, descriptor_scens);double t11 = getTickCount();cout << “AKAZE cost time:” << ((t11 – t00) / getTickFrequency()) << endl;// BFmatchvector<DMatch> matches;BFMatcher matcher;Mat AKAZE_Img;matcher.match(descriptor_obj, descriptor_scens, matches, Mat());vector<DMatch> good_matches;double maxDist=0, minDist=1000;for (size_t i = 0; i < descriptor_obj.rows; i++){double dist = matches[i].distance;if (dist < minDist) { minDist = dist; }if (dist > minDist) { maxDist = dist; }}for (size_t i = 0; i < descriptor_obj.rows; i++){if (matches[i].distance < max(2.0 * minDist, 0.02)) {good_matches.push_back(matches[i]);}}drawMatches(image, keypoints_obj,image2, keypoints_scens,good_matches, AKAZE_Img,Scalar::all(-1), Scalar::all(-1),vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);imshow(“AKAZE_Img”, AKAZE_Img);// flann_matchFlannBasedMatcher flann_matcher(new flann::LshIndexParams(20, 10, 2));vector<DMatch> flann_matches;Mat flann_AKAZE_Img;flann_matcher.match(descriptor_obj, descriptor_scens, flann_matches, Mat());drawMatches(image, keypoints_obj,image2, keypoints_scens,flann_matches, flann_AKAZE_Img,Scalar::all(-1), Scalar::all(-1),vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);imshow(“flann_AKAZE_Img”, flann_AKAZE_Img);}
54424646