📜  opencv c++ 特征检测 - C++ (1)

📅  最后修改于: 2023-12-03 15:18:07.206000             🧑  作者: Mango

Opencv C++ 特征检测

简介

Opencv是一个跨平台的计算机视觉库,其中包括很多常用的图像处理和计算机视觉的算法。其中特征检测功能是计算机视觉领域的一个重要研究领域,其应用广泛,包括目标识别、物体跟踪、图像匹配等等。

本文将带领大家学习如何使用Opencv C++实现特征检测功能,包括SIFT、SURF、ORB、AKAZE等算法,并给出相应的代码示例。

SIFT
算法介绍

尺度不变特征变换(Scale-invariant feature transform,SIFT)是一种计算机视觉的算法,可用于提取适用于物体识别等应用程序的局部特征。此算法由 David Lowe 在 1999 年发表,2004 年完善。

SIFT 算法由四步构成:

  1. 尺度空间极值检测
  2. 关键点定位
  3. 方向分配
  4. 关键点描述
代码示例
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/features2d.hpp>
#include <opencv2/xfeatures2d/nonfree.hpp>

using namespace cv;
using namespace cv::xfeatures2d;

int main()
{
    Mat img1 = imread("/path/to/img1.jpg", IMREAD_GRAYSCALE);
    Mat img2 = imread("/path/to/img2.jpg", IMREAD_GRAYSCALE);

    Ptr<SIFT> sift = SIFT::create(0, 3, 0.04, 10, 1.6);
    std::vector<KeyPoint> keypoints1, keypoints2;
    Mat descriptors1, descriptors2;

    sift->detectAndCompute(img1, noArray(), keypoints1, descriptors1);
    sift->detectAndCompute(img2, noArray(), keypoints2, descriptors2);

    Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create("BruteForce");
    std::vector<DMatch> matches;
    matcher->match(descriptors1, descriptors2, matches);

    Mat img_matches;
    drawMatches(img1, keypoints1, img2, keypoints2, matches, img_matches);

    imshow("SIFT matches", img_matches);
    waitKey(0);

    return 0;
}
SURF
算法介绍

加速稳健特征(Speeded Up Robust Features,SURF)是一种计算机视觉的算法。它是对尺度不变特征变换(SIFT)算法加速与改进得来的。因为 SURF 算法提取速度更快,同时特征点的匹配精度和区分度更高,所以在实际应用中使用较为广泛。

SURF 算法由四步构成:

  1. 构建高斯金字塔和高斯差分金字塔
  2. 计算尺度不变特征
  3. 计算主方向和描述子
  4. 特征匹配
代码示例
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/features2d.hpp>
#include <opencv2/xfeatures2d/nonfree.hpp>

using namespace cv;
using namespace cv::xfeatures2d;

int main()
{
    Mat img1 = imread("/path/to/img1.jpg", IMREAD_GRAYSCALE);
    Mat img2 = imread("/path/to/img2.jpg", IMREAD_GRAYSCALE);

    Ptr<SURF> surf = SURF::create(100);
    std::vector<KeyPoint> keypoints1, keypoints2;
    Mat descriptors1, descriptors2;

    surf->detectAndCompute(img1, noArray(), keypoints1, descriptors1);
    surf->detectAndCompute(img2, noArray(), keypoints2, descriptors2);

    Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create("FlannBased");
    std::vector<DMatch> matches;
    matcher->match(descriptors1, descriptors2, matches);

    Mat img_matches;
    drawMatches(img1, keypoints1, img2, keypoints2, matches, img_matches);

    imshow("SURF matches", img_matches);
    waitKey(0);

    return 0;
}
ORB
算法介绍

Oriented FAST and Rotated BRIEF(ORB)是一种计算机视觉的算法,是为了克服 SIFT 和 SURF 两种算法的缺点而提出的。ORB 算法的特点是速度快,特征点多,描述子维数小。

ORB 算法由两步构成:

  1. 关键点检测:使用 Oriented FAST 检测关键点
  2. 描述子生成:使用 Rotated BRIEF 生成描述子
代码示例
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/features2d.hpp>

using namespace cv;

int main()
{
    Mat img1 = imread("/path/to/img1.jpg", IMREAD_GRAYSCALE);
    Mat img2 = imread("/path/to/img2.jpg", IMREAD_GRAYSCALE);

    Ptr<ORB> orb = ORB::create(5000, 1.2, 8, 31, 0, 2, ORB::HARRIS_SCORE, 31, 20);
    std::vector<KeyPoint> keypoints1, keypoints2;
    Mat descriptors1, descriptors2;

    orb->detectAndCompute(img1, noArray(), keypoints1, descriptors1);
    orb->detectAndCompute(img2, noArray(), keypoints2, descriptors2);

    BFMatcher matcher(NORM_HAMMING);
    std::vector<DMatch> matches;
    matcher.match(descriptors1, descriptors2, matches);

    Mat img_matches;
    drawMatches(img1, keypoints1, img2, keypoints2, matches, img_matches);

    imshow("ORB matches", img_matches);
    waitKey(0);

    return 0;
}
AKAZE
算法介绍

Accelerated-KAZE(AKAZE)是一种计算机视觉的算法,是一种特征检测和描述子生成算法。它通过特有的技巧在不同尺度下进行了极值鲁棒性特征提取和描述。

AKAZE 算法由三步构成:

  1. 构建对比度尺度空间
  2. 极值点提取
  3. 特征描述
代码示例
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/features2d.hpp>
#include <opencv2/xfeatures2d/nonfree.hpp>

using namespace cv;
using namespace cv::xfeatures2d;

int main()
{
    Mat img1 = imread("/path/to/img1.jpg", IMREAD_GRAYSCALE);
    Mat img2 = imread("/path/to/img2.jpg", IMREAD_GRAYSCALE);

    Ptr<AKAZE> akaze = AKAZE::create();
    std::vector<KeyPoint> keypoints1, keypoints2;
    Mat descriptors1, descriptors2;

    akaze->detectAndCompute(img1, noArray(), keypoints1, descriptors1);
    akaze->detectAndCompute(img2, noArray(), keypoints2, descriptors2);

    Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create("BruteForce-Hamming");
    std::vector<DMatch> matches;
    matcher->match(descriptors1, descriptors2, matches);

    Mat img_matches;
    drawMatches(img1, keypoints1, img2, keypoints2, matches, img_matches);

    imshow("AKAZE matches", img_matches);
    waitKey(0);

    return 0;
}
总结

本文介绍了Opencv C++实现特征检测的四种算法:SIFT、SURF、ORB、AKAZE,并给出了相应的代码示例。不同的算法适用于不同的应用场景,需要根据实际情况选择合适的算法。