KAZE算法是由法国学者在在2012年的ECCV会议中提出的,是一种比SIFT更稳定的特征检测算法。KAZE算法是基于非线性尺度空间的算法,KAZE 特征对旋转、尺度、有限仿射具有不变性,并且在不同尺度上具有更多的独特性,但代价是计算时间适度增加。

KAZE算法与SIFT算法不一样,它采用的是非线性扩散滤波法。 具体地,非线性扩散滤波法是将图像亮度(L)在不同尺度上的变化视为某种形式的流动函数(flow function)的散度(divergence),可以通过非线性偏微分方程来描述:

Opencv  KAZE特征检测_角点

通过设置合适的传导函数 c(x,y,t) ,可以使得扩散自适应于图像的局部结构。传导函数可以是标量、也可以是张量。时间t作为尺度参数,其值越大、则图像的表示形式越简单。 Perona和Malik提出了传导函数的构造方式:

Opencv  KAZE特征检测_描述符_02

其中函数g1优先保留高对比度的边缘,g2优先保留宽度较大的区域,g3能够有效平滑区域内部而保留边界信息(KAZE代码中默认采用函数g2) 。

API介绍

static Ptr<KAZE> create(bool extended=false, bool upright=false,float threshold = 0.001f,int nOctaves = 4, int nOctaveLayers = 4,KAZE::DiffusivityType diffusivity = KAZE::DIFF_PM_G2);
/*******************************************************************
*			extended: 					设置以启用扩展(128 字节)描述符的提取		
*			upright:	    			设置为启用垂直描述符(非旋转不变)
*			threshold:					响应阈值
*			nOctaves:  					图像的最大倍频程演化
*			nOctaveLayers:				每个比例级别的默认子级别数		
*			diffusivity:  				扩散型
*							DIFF_PM_G1
*							DIFF_PM_G2
*							DIFF_WEICKERT 
*							DIFF_CHARBONNIER
*********************************************************************/
virtual void detect( InputArray image,std::vector<KeyPoint>& keypoints,InputArray mask=noArray());
/*******************************************************************
*			image: 				输入图				
*			keypoints:	        角点信息
*			mask:				计算亚像素角点区域大小			
*********************************************************************/
void drawKeypoints( InputArray image, const std::vector<KeyPoint>& keypoints, InputOutputArray outImage,const Scalar& color=Scalar::all(-1), DrawMatchesFlags flags=DrawMatchesFlags::DEFAULT );
/*******************************************************************
*			image: 				输入图				
*			keypoints:	        角点信息
*			outImage:			输出图
*			color:  			颜色
*			flags:				绘制匹配标记			
*********************************************************************/

综合代码

#include <iostream>
#include <map>
#include <new>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
class KAZEFeature
{
public:
	KAZEFeature() :img(imread("mm.jpg"))
	{
		result["img"] = img;
	}
	void TestKAZE()
	{
		Ptr<KAZE> kaze = KAZE::create();
		kaze->detect(img, point);
		drawKeypoints(img, point, result["kaze"], Scalar(255, 0, 255));
	}
	void Show()
	{
		for (auto& v : result)
		{
			imshow(v.first, v.second);
		}
		waitKey(0);
	}
protected:
	Mat img;
	vector<KeyPoint> point;
	map<string, Mat> result;
};
int  main()
{
	unique_ptr<KAZEFeature> p(new KAZEFeature);
	p->TestKAZE();
	p->Show();
	return 0;
}

Opencv  KAZE特征检测_#include_03