Opencv(C++)系列学习---SIFT、SURF、ORB算子特征检测

简介: Opencv(C++)系列学习---SIFT、SURF、ORB算子特征检测

         对于特征检测和描述子的运行原理本文先不做具体介绍,在后续的更新中会依次详细解释。本文主要介绍常用三种特征检测算法的参数信息和简单应用。

1.SIFT、SURF、ORB三种算子的参数介绍

【1】SIFT算子定义介绍

static Ptr<SIFT> create(
    int  nfeatures =0,//需要的特征点的数量,是对特征点的质量进行排名,返回最好的前几个;
    int  n0ctaveLayers =3,//金字塔的层数;
    double contrastThrehold =0.04,//过滤特征点的阈值;
    double edgeThreshold =10;//过滤边缘效应的阈值;
    double sigma=1.6;//用于预处理光滑的;

(1)对于nfeature参数是需要的特征点的数量,当设置为0是,返回找到的所有特征点

(2)对于n0ctavelayers计算金字塔的层数是在设定值的基础上加3。

(3)对于contrasthreshold阈值,是过滤掉质量较差的阈值,值越大,过滤的越多。

(4)edgeThreshold过滤边缘效应的阈值,值越大,过滤的越少。

(5)sigma用于图像的光滑预处理,在图像中存在噪声或者其他干扰的情况下,值大一些还是挺有效果的。

【2】SURF算子定义介绍

static Ptr<SURF> create(
double hessianThreshold=100,//SURF中使用的hessian关键点检测器的阈值
int nOctaves = 4, //关键点检测器将使用的金字塔组数量
int nOctaveLayers = 3,//高斯金字塔每个组内图像的层数
bool extended = false, //扩展描述符标志(true使用扩展的128个元素的描述符,false使用64个元素的描述符)
bool upright = false//旋转的特征标志(true不计算方向,false计算方向)
);

检测流程如下:

(1)尺度空间的极值检测:搜索所有尺度空间上的图像,通过Hessian来识别潜在的对尺度和选择不变的兴趣点

(2)特征点过滤并进行精确定位

(3)特征方向赋值:统计特征点圆形领域内的Harr小波特征。即在60°扇形内,每次将60°扇形区域旋转0.2弧度进行统计,将值最大的哪个扇形的方向作为特征点的主方向

(4)特征点描述:沿着特征点主方向周围的邻域内,取4X4X4个矩形区域,统计每个小区域的Harr特征,然后每个区域得到一个4维的特征向量。一个特征点共有64维的特征向量作为SURF特征的描述子。

【3】ORB算子定义介绍

      ORB的全称是ORiented Brief,采用FAST(features from accelerated segment test)算法来检测特征点。与Brisk,AKAZE类似,ORB也分两部分,即特征点提取和特征点描述。特征提取是由FAST(Features from Accelerated Segment Test)算法发展来的,它基于特征点周围的图像灰度值,检测候选特征点周围一圈的像素值,如果候选点周围领域内有足够多的像素点与该候选点的灰度值差别够大,则认为该候选点为一个特征点。而特征点描述是根据BRIEF(Binary Robust Independent Elementary Features)特征描述算法改进的。

       将FAST特征点的检测方法与BRIEF特征描述子结合起来,并在它们原来的基础上做了改进与优化。据说ORB算法的速度是sift的100倍,是surf的10倍。ORB算法是为解决BRIEF的缺陷而改进的,主要解决两个缺点:噪声敏感、旋转不变性。

Ptr<ORB> create(
int nfeatures =500,
float scaleFactor=1.2f,
int nlevels=8,
int edgeThreshold=31,
int firstLevel=0,
int WTA_K=2,
int scoreTyoe=0,
int patchSize=31,
int fastThreshold=20
);

(1)nfeatures 为最多提取的特征点的数量;

(2)scaleFactor - 金字塔图像之间的尺度参数,类似于SIFT中的;

(3)nlevels – 高斯金字塔的层数;

(4)edgeThreshold – 边缘阈值,这个值主要是根据后面的patchSize来定的,靠近边缘edgeThreshold以内的像素是不检测特征点的。

(5)firstLevel - 看过SIFT都知道,我们可以指定第一层的索引值,这里默认为0。

(6)WET_K - 用于产生BIREF描述子的 点对的个数,一般为2个,也可以设置为3个或4个,那么这时候描述子之间的距离计算就不能用汉明距离了,而是应该用一个变种。OpenCV中,如果设置WET_K = 2,则选用点对就只有2个点,匹配的时候距离参数选择NORM_HAMMING,如果WET_K设置为3或4,则BIREF描述子会选择3个或4个点,那么后面匹配的时候应该选择的距离参数为NORM_HAMMING2。

(7)scoreType - 用于对特征点进行排序的算法,你可以选择HARRIS_SCORE,也可以选择FAST_SCORE,但是它也只是比前者快一点点而已。

(8)patchSize – 用于计算BIREF描述子的特征点邻域大小。

(9)FastThreshold-是Fast特征检测器的阈值。

关于ORB算子的更多介绍:

2.代码示例

#include<opencv2\opencv.hpp>
#include<opencv2\xfeatures2d.hpp>
#include<opencv2\imgproc\imgproc.hpp>
#include<opencv2\highgui\highgui.hpp>
#include<opencv2\xfeatures2d\nonfree.hpp>
#include<iostream>
using namespace std;
using namespace cv;
using namespace cv::xfeatures2d;
int main(int argc,char** argv)
{
  //【0】改变字体颜色
  system("color 2F");
  //【1】载入源图片并显示
  Mat srcImage1 = imread("E:\\乔大花进度\\11-17\\surf特征检测\\1.jpg",1);
  Mat srcImage2 = imread("E:\\乔大花进度\\11-17\\surf特征检测\\2.jpg", 1);
  //【2】显示图片
  imshow("原始图1",srcImage1);
  imshow("原始图2",srcImage2);
  int minHessian = 400;//默认值为100
  vector<KeyPoint>keyPoints, keyPoints1;
  Mat resultImg, resultImage1;
  //关于定义的方法主要有两种
  //第一种指针形式定义
  //  Ptr<SURF\SIFT\ORB>detector = SURF\SIFT\ORB::create(minHessian, 4, 3, false, false);
  //第二种算子形式定义
  //SiftFeatureDetector\SurfFeatureDetector定义
  //第一种定义方式更普遍使用
  //SURF特征检测  //也可以写成SURF::create(minHessian)
  Ptr<SURF>detector = SURF::create(minHessian, 4, 3, false, false);
  
  detector->detect(srcImage1, keyPoints, Mat());
    //绘制关键点
  drawKeypoints(srcImage1, keyPoints, resultImg, Scalar::all(-1), DrawMatchesFlags::DEFAULT);
  imshow("KetPoint image", resultImg);
  //SIFT特征检测
  Ptr<SIFT>detector1 = SIFT::create();
  detector1->detect(srcImage2, keyPoints1, Mat());
  //绘制关键点
  drawKeypoints(srcImage2, keyPoints1, resultImage1, Scalar::all(-1), DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
  imshow("KetPoint image1" ,resultImage1);
  waitKey(0);
  system("pause");
  return 0;
}

(1)在特征检测器定义完成后,通过detect可以提取检测出的特征点,存储在keypoints中。

(2)关于drawkeypoints算子是用来绘制显示检测的特征点的。其中显示方式有两种常用的

第一种是默认的DEFAULT,小圆圈圈出关键点。第二种是DRAW_RICH_KEYPOINTS,用带有半径和方向的圆圈出关键点。

显示结果:

相关文章
|
算法 网络安全 区块链
2023/11/10学习记录-C/C++对称分组加密DES
本文介绍了对称分组加密的常见算法(如DES、3DES、AES和国密SM4)及其应用场景,包括文件和视频加密、比特币私钥加密、消息和配置项加密及SSL通信加密。文章还详细展示了如何使用异或实现一个简易的对称加密算法,并通过示例代码演示了DES算法在ECB和CBC模式下的加密和解密过程,以及如何封装DES实现CBC和ECB的PKCS7Padding分块填充。
387 4
2023/11/10学习记录-C/C++对称分组加密DES
|
XML 机器学习/深度学习 人工智能
使用 OpenCV 和 Python 轻松实现人脸检测
本文介绍如何使用OpenCV和Python实现人脸检测。首先,确保安装了OpenCV库并加载预训练的Haar特征模型。接着,通过读取图像或视频帧,将其转换为灰度图并使用`detectMultiScale`方法进行人脸检测。检测到的人脸用矩形框标出并显示。优化方法包括调整参数、多尺度检测及使用更先进模型。人脸检测是计算机视觉的基础技术,具有广泛应用前景。
680 10
|
C++ 开发者
C++学习之继承
通过继承,C++可以实现代码重用、扩展类的功能并支持多态性。理解继承的类型、重写与重载、多重继承及其相关问题,对于掌握C++面向对象编程至关重要。希望本文能为您的C++学习和开发提供实用的指导。
224 16
|
机器学习/深度学习 计算机视觉
目标检测笔记(六):如何结合特定区域进行目标检测(基于OpenCV的人脸检测实例)
本文介绍了如何使用OpenCV进行特定区域的目标检测,包括人脸检测实例,展示了两种实现方法和相应的代码。
499 1
目标检测笔记(六):如何结合特定区域进行目标检测(基于OpenCV的人脸检测实例)
|
编译器 C语言 C++
配置C++的学习环境
【10月更文挑战第18天】如果想要学习C++语言,那就需要配置必要的环境和相关的软件,才可以帮助自己更好的掌握语法知识。 一、本地环境设置 如果您想要设置 C++ 语言环境,您需要确保电脑上有以下两款可用的软件,文本编辑器和 C++ 编译器。 二、文本编辑器 通过编辑器创建的文件通常称为源文件,源文件包含程序源代码。 C++ 程序的源文件通常使用扩展名 .cpp、.cp 或 .c。 在开始编程之前,请确保您有一个文本编辑器,且有足够的经验来编写一个计算机程序,然后把它保存在一个文件中,编译并执行它。 Visual Studio Code:虽然它是一个通用的文本编辑器,但它有很多插
599 6
|
Ubuntu Linux 编译器
Linux/Ubuntu下使用VS Code配置C/C++项目环境调用OpenCV
通过以上步骤,您已经成功在Ubuntu系统下的VS Code中配置了C/C++项目环境,并能够调用OpenCV库进行开发。请确保每一步都按照您的系统实际情况进行适当调整。
2966 3
|
算法 计算机视觉 Python
圆形检测算法-基于颜色和形状(opencv)
该代码实现了一个圆检测算法,用于识别视频中的红色、白色和蓝色圆形。通过将图像从RGB转换为HSV颜色空间,并设置对应颜色的阈值范围,提取出目标颜色的区域。接着对这些区域进行轮廓提取和面积筛选,使用霍夫圆变换检测圆形,并在原图上绘制检测结果。
700 0
|
计算机视觉
Opencv学习笔记(三):图像二值化函数cv2.threshold函数详解
这篇文章详细介绍了OpenCV库中的图像二值化函数`cv2.threshold`,包括二值化的概念、常见的阈值类型、函数的参数说明以及通过代码实例展示了如何应用该函数进行图像二值化处理,并展示了运行结果。
4297 0
Opencv学习笔记(三):图像二值化函数cv2.threshold函数详解
|
算法 计算机视觉
opencv图像形态学
图像形态学是一种基于数学形态学的图像处理技术,它主要用于分析和修改图像的形状和结构。
341 4
|
存储 计算机视觉
Opencv的基本操作(一)图像的读取显示存储及几何图形的绘制
本文介绍了使用OpenCV进行图像读取、显示和存储的基本操作,以及如何绘制直线、圆形、矩形和文本等几何图形的方法。
Opencv的基本操作(一)图像的读取显示存储及几何图形的绘制