OpenCV 4.x API 详解与C++实例-特征检测与描述

第一节 特征检测与描述

OpenCV提供了丰富的特征检测算法,比如SIFT(Scale Invariant Feature Transform)、AffineFeature、AgastFeatureDetector、AKAZE、BRISK、FastFeatureDetector、GFTTDetector、KAZE、MSER、ORB、SimpleBlobDetector等

1、SIFT


尺度不变特征变换算法提取图像特征

SIFT类继承了cv::Feature2D类,通过create静态方法创建。

static Ptr cv::SIFT::create(int nfeatures = 0,int nOctaveLayers = 3,double contrastThreshold = 0.04,double edgeThreshold = 10,double sigma = 1.6)

参数如下:

参数名称 参数描述
nfeatures 保留的最佳特征的数量;特征按其得分排名
nOctaveLayers 每个八度中的层数。 3是D.Lowe谁中使用的值。 八度的数量是根据图像分辨率自动计算的。
contrastThreshold 对比度阈值,用于过滤半均匀(低对比度)区域中的弱点。 阈值越大,检测器产生的特征越少。
edgeThreshold 用于过滤边缘特征的阈值。 请注意,其含义与contrastThreshold不同,即edgeThreshold越大,滤除的特征越少(保留的特征越多)。
sigma 高斯的sigma应用于八度为#0的输入图像。 如果使用带软镜头的弱相机拍摄图像,则可能需要减少数量。

注意:应用过滤时,对比度阈值将被nOctaveLayers除。 当nOctaveLayers设置为默认值并且如果要使用D.Lowe论文中使用的值0.03时,请将此参数设置为0.09。

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;

int main()
{
    // 读取图像
    cv::Mat src = cv::imread("images/f1.jpg");
    if(src.empty()){
        cerr << "cannot read image.\n";
        return EXIT_FAILURE;
    }

    // 转换成灰度图像
    cv::Mat gray;
    cv::cvtColor(src,gray,cv::COLOR_BGR2GRAY);

    // 创建SIFT特征提取器
    cv::Ptr<cv::SIFT> feature = cv::SIFT::create(1024,3,0.04,120,1.5);

    // 检测特征点
    vector<cv::KeyPoint> keypoints;
    cv::Mat descriptor;
    feature->detectAndCompute(gray,cv::Mat(),keypoints,descriptor);

    // 绘制特征点
    cv::Mat output;
    cv::drawKeypoints(src,keypoints,output,cv::Scalar(0,0,255));

    cv::imshow("src",src);
    cv::imshow("output",output);

    cv::waitKey();

    return 0;
}

在这里插入图片描述

2、 AffineFeature


用于实现使检测器和提取器具有仿射不变的包装器的类,在[Guoshen Yu and Jean-Michel Morel. Asift: An algorithm for fully affine invariant comparison. Image Processing On Line, 1:11–38, 2011.]中描述为ASIFT。

AffineFeature类继承了cv::Feature2D类,通过create静态方法创建。

static Ptr cv::AffineFeature::create(const Ptr< Feature2D > & backend,int maxTilt = 5,int minTilt = 0,float tiltStep = 1.4142135623730951f,float rotateStepBase = 72)

参数如下:

参数 参数描述
backend 用作后端的检测器/提取器。
maxTilt 倾斜系数的最高功率指标。 在纸张中使用5作为倾斜采样范围n。
minTilt 最低的倾斜系数功率指数。 本文使用0。
tiltStep 倾斜采样步骤δt。
rotateStepBase 旋转采样阶跃系数b
#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;

int main()
{

    // 读取图像
    cv::Mat src = cv::imread("images/f1.jpg");
    if(src.empty()){
        cerr << "cannot read image.\n";
        return EXIT_FAILURE;
    }

    // 转换成灰度图像
    cv::Mat gray;
    cv::cvtColor(src,gray,cv::COLOR_BGR2GRAY);

    // 使用SIFT特征检测算法创建
    cv::Ptr<cv::AffineFeature> feature = cv::AffineFeature::create(cv::SIFT::create(128));

    // 检测特征点
    vector<cv::KeyPoint> keypoints;
    cv::Mat descriptor;
    feature->detectAndCompute(gray,cv::Mat(),keypoints,descriptor);

    // 绘制特征点
    cv::Mat output;
    cv::drawKeypoints(src,keypoints,output,cv::Scalar(0,0,255));

    cv::imshow("src",src);
    cv::imshow("output",output);

    cv::waitKey();

    return 0;
}

在这里插入图片描述

3、AgastFeatureDetector


使用AGAST方法进行特征检测的包装类。

AgastFeatureDetector类继承了cv::Feature2D类,通过create静态方法创建。

static Ptr cv::AgastFeatureDetector::create(int threshold = 10,bool nonmaxSuppression = true,AgastFeatureDetector::DetectorType type = AgastFeatureDetector::OAST_9_16)

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;

int main()
{
    // 读取图像
    cv::Mat src = cv::imread("images/f1.jpg");
    if(src.empty()){
        cerr << "cannot read image.\n";
        return EXIT_FAILURE;
    }

    // 转换成灰度图像
    cv::Mat gray;
    cv::cvtColor(src,gray,cv::COLOR_BGR2GRAY);

    // 创建AgastFeatureDetector特征提取器
    cv::Ptr<cv::AgastFeatureDetector> feature = cv::AgastFeatureDetector::create();

    // 检测特征点
    vector<cv::KeyPoint> keypoints;
    cv::Mat descriptor;
    feature->detect(gray,keypoints);

    // 绘制特征点
    cv::Mat output;
    cv::drawKeypoints(src,keypoints,output,cv::Scalar(0,0,255));

    cv::imshow("src",src);
    cv::imshow("output",output);

    cv::waitKey();

    return 0;
}

在这里插入图片描述

4、AKAZE


实现AKAZE关键点检测器和描述符提取器的类,在[Pablo F Alcantarilla, Jesús Nuevo, and Adrien Bartoli. Fast explicit diffusion for accelerated features in nonlinear scale spaces. Trans. Pattern Anal. Machine Intell, 34(7):1281–1298, 2011.]中进行了描述。

AKAZE类继承了cv::Feature2D类,通过create静态方法创建。

static Ptr cv::AKAZE::create (AKAZE::DescriptorType descriptor_type = AKAZE::DESCRIPTOR_MLDB,int descriptor_size = 0,int descriptor_channels = 3,float threshold = 0.001f,int nOctaves = 4,int nOctaveLayers = 4,KAZE::DiffusivityType diffusivity = KAZE::DIFF_PM_G2)

参数名称 参数描述
descriptor_type 提取的描述符的类型:DESCRIPTOR_KAZE,DESCRIPTOR_KAZE_UPRIGHT,DESCRIPTOR_MLDB或DESCRIPTOR_MLDB_UPRIGHT。
descriptor_size 描述符的大小(以位为单位)。 0->全尺寸
descriptor_channels 描述符中的通道数(1、2、3)
threshold 检测器响应阈值以接受点
nOctaves 图像的最大八度演变
nOctaveLayers 每个比例级别的默认子级别数
diffusivity 扩散类型。 DIFF_PM_G1,DIFF_PM_G2,DIFF_WEICKERT或DIFF_CHARBONNIER
#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;

int main()
{
    // 读取图像
    cv::Mat src = cv::imread("images/f1.jpg");
    if(src.empty()){
        cerr << "cannot read image.\n";
        return EXIT_FAILURE;
    }

    // 转换成灰度图像
    cv::Mat gray;
    cv::cvtColor(src,gray,cv::COLOR_BGR2GRAY);

    // 创建AKAZE特征提取器
    cv::Ptr<cv::AKAZE> feature = cv::AKAZE::create();

    // 检测特征点
    vector<cv::KeyPoint> keypoints;
    cv::Mat descriptor;
    feature->detect(gray,keypoints);

    // 绘制特征点
    cv::Mat output;
    cv::drawKeypoints(src,keypoints,output,cv::Scalar(0,0,255));

    cv::imshow("src",src);
    cv::imshow("output",output);

    cv::waitKey();

    return 0;
}

在这里插入图片描述

5、BRISK


实现BRISK关键点检测器和描述符提取器的类,在[Stefan Leutenegger, Margarita Chli, and Roland Yves Siegwart. Brisk: Binary robust invariant scalable keypoints. In Computer Vision (ICCV), 2011 IEEE International Conference on, pages 2548–2555. IEEE, 2011.]中进行了描述。

BRISK类继承了cv::Feature2D类,通过create静态方法创建。

static Ptr cv::BRISK::create(int thresh = 30,int octaves=3,float patternScale=1.0f)

参数名称 参数描述
thresh AGAST检测阈值得分。
octaves 检测八度。 使用0进行单刻度。
patternScale 将此比例应用于用于采样关键点邻域的模式。

其他函数重载形式:

自定义模式的BRISK构造函数。

static Ptr cv::BRISK::create (const std::vector< float > & radiusList,const std::vector< int > & numberList,float dMax = 5.85f,float dMin = 8.2f,const std::vector< int > & indexChange=std::vector< int >())

参数名称 参数描述
numberList 定义采样圆上的采样点数。 必须与radiusList大小相同。
radiusList 定义在关键点周围采样的半径(以像素为单位)(对于关键点比例1)。
dMax 用于描述符形成的短配对的阈值(对于关键点比例1,以像素为单位)。
dMin 用于方向确定的长配对的阈值(对于关键点比例1,以像素为单位)。
indexChange 位的索引重新映射。

static Ptr cv::BRISK::create (int thresh,int octaves,const std::vector< float > & radiusList,const std::vector< int > & numberList,float dMax = 5.85f,float dMin = 8.2f,const std::vector< int > & indexChange = std::vector< int >())

参数名称 参数描述
thresh AGAST检测阈值得分。
octaves 检测八度。 使用0进行单刻度。
radiusList 定义在关键点周围采样的半径(以像素为单位)(对于关键点比例1)。
numberList 定义采样圆上的采样点数。 必须与radiusList大小相同。
dMax 用于描述符形成的短配对的阈值(对于关键点比例1,以像素为单位)。
dMin 用于方向确定的长配对的阈值(对于关键点比例1,以像素为单位)。
indexChange 位的索引重新映射。
#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;

int main()
{
    // 读取图像
    cv::Mat src = cv::imread("images/f1.jpg");
    if(src.empty()){
        cerr << "cannot read image.\n";
        return EXIT_FAILURE;
    }

    // 转换成灰度图像
    cv::Mat gray;
    cv::cvtColor(src,gray,cv::COLOR_BGR2GRAY);

    // 创建BRISK特征提取器
    cv::Ptr<cv::BRISK> feature = cv::BRISK::create();

    // 检测特征点
    vector<cv::KeyPoint> keypoints;
    cv::Mat descriptor;
    feature->detect(gray,keypoints);

    // 绘制特征点
    cv::Mat output;
    cv::drawKeypoints(src,keypoints,output,cv::Scalar(0,0,255));

    cv::imshow("src",src);
    cv::imshow("output",output);

    cv::waitKey();

    return 0;
}

在这里插入图片描述

6、FastFeatureDetector


使用FAST方法进行特征检测的包装类。FastFeatureDetector类继承了cv::Feature2D类,通过create静态方法创建。

static Ptr cv::FastFeatureDetector::create(int threshold = 10,bool nonmaxSuppression = true,FastFeatureDetector::DetectorType type = FastFeatureDetector::TYPE_9_16)

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;

int main()
{
    // 读取图像
    cv::Mat src = cv::imread("images/f1.jpg");
    if(src.empty()){
        cerr << "cannot read image.\n";
        return EXIT_FAILURE;
    }

    // 转换成灰度图像
    cv::Mat gray;
    cv::cvtColor(src,gray,cv::COLOR_BGR2GRAY);

    // 创建FastFeatureDetector特征提取器
    cv::Ptr<cv::FastFeatureDetector> feature = cv::FastFeatureDetector::create();

    // 检测特征点
    vector<cv::KeyPoint> keypoints;
    cv::Mat descriptor;
    feature->detect(gray,keypoints);

    // 绘制特征点
    cv::Mat output;
    cv::drawKeypoints(src,keypoints,output,cv::Scalar(0,0,255));

    cv::imshow("src",src);
    cv::imshow("output",output);

    cv::waitKey();

    return 0;
}

在这里插入图片描述

7、GFTTDetector


使用goodFeaturesToTrack函数包装特征的包装类。GFTTDetector类继承了cv::Feature2D类,通过create静态方法创建。

static Ptr cv::GFTTDetector::create(int maxCorners=1000,double qualityLevel = 0.01,double minDistance = 1,int blockSize = 3,bool useHarrisDetector = false,double k = 0.04)

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;

int main()
{
    // 读取图像
    cv::Mat src = cv::imread("images/f1.jpg");
    if(src.empty()){
        cerr << "cannot read image.\n";
        return EXIT_FAILURE;
    }

    // 转换成灰度图像
    cv::Mat gray;
    cv::cvtColor(src,gray,cv::COLOR_BGR2GRAY);

    // 创建FastFeatureDetector特征提取器
    cv::Ptr<cv::GFTTDetector> feature = cv::GFTTDetector::create();

    // 检测特征点
    vector<cv::KeyPoint> keypoints;
    cv::Mat descriptor;
    feature->detect(gray,keypoints);

    // 绘制特征点
    cv::Mat output;
    cv::drawKeypoints(src,keypoints,output,cv::Scalar(0,0,255));

    cv::imshow("src",src);
    cv::imshow("output",output);

    cv::waitKey();

    return 0;
}

在这里插入图片描述

8、KAZE


实现KAZE关键点检测器和描述符提取器的类,在[Pablo Fernández Alcantarilla, Adrien Bartoli, and Andrew J Davison. Kaze features. In Computer Vision–ECCV 2012, pages 214–227. Springer, 2012.]中进行了描述。

AKAZE描述符只能与KAZE或AKAZE关键点一起使用。AKAZE类继承了cv::Feature2D类,通过create静态方法创建。参数如下:

static Ptr cv::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
#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;

int main()
{
    // 读取图像
    cv::Mat src = cv::imread("images/f1.jpg");
    if(src.empty()){
        cerr << "cannot read image.\n";
        return EXIT_FAILURE;
    }

    // 转换成灰度图像
    cv::Mat gray;
    cv::cvtColor(src,gray,cv::COLOR_BGR2GRAY);

    // 创建FastFeatureDetector特征提取器
    cv::Ptr<cv::KAZE> feature = cv::KAZE::create();

    // 检测特征点
    vector<cv::KeyPoint> keypoints;
    cv::Mat descriptor;
    feature->detect(gray,keypoints);

    // 绘制特征点
    cv::Mat output;
    cv::drawKeypoints(src,keypoints,output,cv::Scalar(0,0,255));

    cv::imshow("src",src);
    cv::imshow("output",output);

    cv::waitKey();

    return 0;
}

在这里插入图片描述

9、MSER


最大限度地稳定的极值区域提取。该类封装了MSER提取算法的所有参数。MSER类继承了cv::Feature2D类,通过create静态方法创建。参数如下:

static Ptr cv::MSER::create(int _delta = 5,int _min_area = 60,int _max_area = 14400,double _max_variation = 0.25,double _min_diversity = .2,int _max_evolution = 200,double _area_threshold = 1.01,double _min_margin = 0.003,int _edge_blur_size = 5)

参数名称 参数描述
_delta 它比较(sizei-sizei-delta)/ sizei-delta
_min_area 修剪小于minArea的区域
_max_area 修剪大于maxArea的区域
_max_variation 修剪该区域的大小与其子面积相似
_min_diversity 对于彩色图像,回溯以切断多样性小于min_diversity的mser
_max_evolution 对于彩色图像,演变步骤
_area_threshold 对于彩色图像,导致重新初始化的面积阈值
_min_margin 对于彩色图像,请忽略过小的边距
_edge_blur_size 对于彩色图像,边缘模糊的光圈大小
#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;

int main()
{
    // 读取图像
    cv::Mat src = cv::imread("images/f1.jpg");
    if(src.empty()){
        cerr << "cannot read image.\n";
        return EXIT_FAILURE;
    }

    // 转换成灰度图像
    cv::Mat gray;
    cv::cvtColor(src,gray,cv::COLOR_BGR2GRAY);

    // 创建FastFeatureDetector特征提取器
    cv::Ptr<cv::MSER> feature = cv::MSER::create();

    // 检测特征点
    vector<cv::KeyPoint> keypoints;
    cv::Mat descriptor;
    feature->detect(gray,keypoints);

    // 绘制特征点
    cv::Mat output;
    cv::drawKeypoints(src,keypoints,output,cv::Scalar(0,0,255));

    cv::imshow("src",src);
    cv::imshow("output",output);

    cv::waitKey();

    return 0;
}

在这里插入图片描述

10、ORB


实现ORB(面向Brief)关键点检测器和描述符提取器的类。

在[Ethan Rublee, Vincent Rabaud, Kurt Konolige, and Gary Bradski. Orb: an efficient alternative to sift or surf. In Computer Vision (ICCV), 2011 IEEE International Conference on, pages 2564–2571. IEEE, 2011.]中描述。 该算法在金字塔中使用FAST来检测稳定的关键点,使用FAST或Harris响应选择最强的特征,使用一阶矩找到它们的方向,并使用Brief来计算描述符(其中随机点对(或k元组)的坐标为 根据测量的方向旋转)。

ORB类继承了cv::Feature2D类,通过create静态方法创建。参数如下:

static Ptr cv::ORB::create(int nfeatures=500,float scaleFactor = 1.2f,int nlevels = 8,int edgeThreshold = 31,int firstLevel = 0,int WTA_K = 2,ORB::ScoreType scoreType = ORB::HARRIS_SCORE,int patchSize = 31,int fastThreshold = 20)

参数 参数描述
nfeatures 保留的最大特征数量。
scaleFactor 金字塔抽取率大于1。scaleFactor == 2表示经典金字塔,其中每个下一个级别的像素比上一个少4倍,但是如此大的比例因子将大大降低特征匹配分数。 另一方面,太接近1的比例因子意味着要覆盖一定的比例范围,您将需要更多的金字塔等级,因此速度会受到影响。
nlevels 金字塔等级的数量。 最小级别的线性大小等于input_image_linear_size / pow(scaleFactor,nlevels-firstLevel)。
edgeThreshold 未检测到特征的边框的大小。 它应该与patchSize参数大致匹配。
firstLevel 要放置源图像的金字塔等级。 先前的层填充有放大的源图像。
WTA_K 产生定向的Brief描述符的每个元素的点数。 默认值2表示“ BRIEF”,我们采用一个随机点对并比较它们的亮度,因此得到0/1响应。 其他可能的值是3和4。例如,3表示我们取3个随机点(当然,这些点坐标是随机的,但它们是从预定义的种子生成的,因此,BRIEF描述符的每个元素都是从确定的 像素矩形),找到最大亮度的点和获胜者的输出指数(0、1或2)。 这样的输出将占用2位,因此将需要Hamming距离的特殊变体,表示为NORM_HAMMING2(每个bin 2位)。 当WTA_K = 4时,我们取4个随机点来计算每个bin(也将占用2位,可能的值为0、1、2或3)。
scoreType 默认的HARRIS_SCORE表示将Harris算法用于对要素进行排名(分数被写入KeyPoint :: score并用于保留最佳nfeatures要素); FAST_SCORE是该参数的替代值,它产生的稳定关键点会稍少一些,但计算速度稍快一些。
patchSize 定向的Brief描述符使用的补丁大小。 当然,在较小的金字塔层上,特征覆盖的感知图像区域将更大。
fastThreshold 快速阈值
#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;

int main()
{
    // 读取图像
    cv::Mat src = cv::imread("images/f1.jpg");
    if(src.empty()){
        cerr << "cannot read image.\n";
        return EXIT_FAILURE;
    }

    // 转换成灰度图像
    cv::Mat gray;
    cv::cvtColor(src,gray,cv::COLOR_BGR2GRAY);

    // 创建FastFeatureDetector特征提取器
    cv::Ptr<cv::ORB> feature = cv::ORB::create();

    // 检测特征点
    vector<cv::KeyPoint> keypoints;
    cv::Mat descriptor;
    feature->detect(gray,keypoints);

    // 绘制特征点
    cv::Mat output;
    cv::drawKeypoints(src,keypoints,output,cv::Scalar(0,0,255));

    cv::imshow("src",src);
    cv::imshow("output",output);

    cv::waitKey();

    return 0;
}

在这里插入图片描述

11、SimpleBlobDetector


用于从图像中提取斑点的类。 SimpleBlobDetector类继承了cv::Feature2D类,通过create静态方法创建。参数如下:

static Ptr cv::SimpleBlobDetector::create(const SimpleBlobDetector::Params & parameters = SimpleBlobDetector::Params())

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;

int main()
{
    // 读取图像
    cv::Mat src = cv::imread("images/f1.jpg");
    if(src.empty()){
        cerr << "cannot read image.\n";
        return EXIT_FAILURE;
    }

    // 转换成灰度图像
    cv::Mat gray;
    cv::cvtColor(src,gray,cv::COLOR_BGR2GRAY);

    // 创建FastFeatureDetector特征提取器
    cv::Ptr<cv::SimpleBlobDetector> feature = cv::SimpleBlobDetector::create();

    // 检测特征点
    vector<cv::KeyPoint> keypoints;
    cv::Mat descriptor;
    feature->detect(gray,keypoints);

    // 绘制特征点
    cv::Mat output;
    cv::drawKeypoints(src,keypoints,output,cv::Scalar(0,0,255));

    cv::imshow("src",src);
    cv::imshow("output",output);

    cv::waitKey();

    return 0;
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/wujuxKkoolerter/article/details/114162810