OpenCV中常用特征提取算法(SURF、ORB、SIFT和AKAZE)用法示例(C++和Python)

OpenCV 中提供了多种常用的特征提取算法 ,广泛应用于图像匹配、拼接、SLAM、物体识别等任务。以下是 OpenCV 中几个主流特征提取算法的 用法总结与代码示例,涵盖 C++ 和 Python 两个版本。


常用特征提取算法列表

算法 特点 是否需额外模块
SIFT(尺度不变特征) 稳定性强、可旋转缩放 xfeatures2d 模块
SURF(加速稳健特征) 快速但专利保护 xfeatures2d 模块
ORB(Oriented FAST + BRIEF) 免费、高速 OpenCV 主模块
AKAZE 适用于非线性尺度空间 OpenCV 主模块
BRISK 二进制描述子、适用于实时应用 OpenCV 主模块

示例一:ORB 特征提取与匹配

Python 版:

python 复制代码
import cv2

# 加载图像
img1 = cv2.imread("image1.jpg", cv2.IMREAD_GRAYSCALE)
img2 = cv2.imread("image2.jpg", cv2.IMREAD_GRAYSCALE)

# 创建 ORB 检测器
orb = cv2.ORB_create()

# 检测关键点和计算描述子
kp1, des1 = orb.detectAndCompute(img1, None)
kp2, des2 = orb.detectAndCompute(img2, None)

# 创建匹配器
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
matches = bf.match(des1, des2)

# 排序并绘制前 20 个匹配点
matches = sorted(matches, key=lambda x: x.distance)
matched_img = cv2.drawMatches(img1, kp1, img2, kp2, matches[:20], None, flags=2)

cv2.imshow("ORB Matches", matched_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

C++ 版:

cpp 复制代码
#include <opencv2/opencv.hpp>
#include <opencv2/features2d.hpp>

int main()
{
    cv::Mat img1 = cv::imread("image1.jpg", cv::IMREAD_GRAYSCALE);
    cv::Mat img2 = cv::imread("image2.jpg", cv::IMREAD_GRAYSCALE);

    cv::Ptr<cv::ORB> orb = cv::ORB::create();

    std::vector<cv::KeyPoint> kp1, kp2;
    cv::Mat des1, des2;
    orb->detectAndCompute(img1, cv::noArray(), kp1, des1);
    orb->detectAndCompute(img2, cv::noArray(), kp2, des2);

    cv::BFMatcher matcher(cv::NORM_HAMMING, true);
    std::vector<cv::DMatch> matches;
    matcher.match(des1, des2, matches);

    std::sort(matches.begin(), matches.end(),
              [](const cv::DMatch& m1, const cv::DMatch& m2) {
                  return m1.distance < m2.distance;
              });

    cv::Mat img_matches;
    cv::drawMatches(img1, kp1, img2, kp2, matches, img_matches);
    cv::imshow("ORB Matches", img_matches);
    cv::waitKey(0);
    return 0;
}

示例二:SIFT 特征提取(需额外模块)

Python 版:

python 复制代码
import cv2

sift = cv2.SIFT_create()
img = cv2.imread("image.jpg", cv2.IMREAD_GRAYSCALE)
kp, des = sift.detectAndCompute(img, None)

img_kp = cv2.drawKeypoints(img, kp, None, flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
cv2.imshow("SIFT Features", img_kp)
cv2.waitKey(0)

注意:SIFT 在 OpenCV 4.x 中已开放为免费使用,需 pip install opencv-contrib-python


C++ 版:

cpp 复制代码
#include <opencv2/opencv.hpp>
#include <opencv2/xfeatures2d.hpp>

int main()
{
    cv::Mat img = cv::imread("image.jpg", cv::IMREAD_GRAYSCALE);
    cv::Ptr<cv::SIFT> sift = cv::SIFT::create();

    std::vector<cv::KeyPoint> keypoints;
    cv::Mat descriptors;
    sift->detectAndCompute(img, cv::noArray(), keypoints, descriptors);

    cv::Mat output;
    cv::drawKeypoints(img, keypoints, output, cv::Scalar::all(-1), cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
    cv::imshow("SIFT", output);
    cv::waitKey(0);
    return 0;
}

示例三:AKAZE 特征提取

Python 版:

python 复制代码
import cv2

akaze = cv2.AKAZE_create()
img = cv2.imread("image.jpg", cv2.IMREAD_GRAYSCALE)
kp, des = akaze.detectAndCompute(img, None)

img_kp = cv2.drawKeypoints(img, kp, None, color=(0,255,0))
cv2.imshow("AKAZE", img_kp)
cv2.waitKey(0)

C++ 版:

cpp 复制代码
#include <opencv2/opencv.hpp>

int main()
{
    cv::Mat img = cv::imread("image.jpg", cv::IMREAD_GRAYSCALE);
    cv::Ptr<cv::AKAZE> akaze = cv::AKAZE::create();

    std::vector<cv::KeyPoint> keypoints;
    cv::Mat descriptors;
    akaze->detectAndCompute(img, cv::noArray(), keypoints, descriptors);

    cv::Mat output;
    cv::drawKeypoints(img, keypoints, output);
    cv::imshow("AKAZE", output);
    cv::waitKey(0);
    return 0;
}

示例四:SURF 特征提取

小提示

SURF 属于专利算法(由 Hessian Matrix 加速构建特征),因此默认在 opencv-python不可用 ,需要使用 opencv-contrib 版本:

  • Python: pip install opencv-contrib-python
  • C++: 编译 OpenCV 时需启用 opencv_contrib,并启用 xfeatures2d 模块。

Python 示例

python 复制代码
import cv2
import numpy as np

# 读取图像
img = cv2.imread("image.jpg", cv2.IMREAD_GRAYSCALE)

# 创建 SURF 对象(阈值越高,检测特征点越少)
surf = cv2.xfeatures2d.SURF_create(hessianThreshold=400)

# 检测并计算特征点和描述子
keypoints, descriptors = surf.detectAndCompute(img, None)

# 绘制关键点
img_kp = cv2.drawKeypoints(img, keypoints, None, (0,255,0), flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)

cv2.imshow("SURF Features", img_kp)
cv2.waitKey(0)
cv2.destroyAllWindows()

C++ 示例

cpp 复制代码
#include <opencv2/opencv.hpp>
#include <opencv2/xfeatures2d.hpp>

int main()
{
    cv::Mat img = cv::imread("image.jpg", cv::IMREAD_GRAYSCALE);
    if (img.empty()) {
        std::cerr << "Cannot load image!" << std::endl;
        return -1;
    }

    // 创建 SURF 检测器
    cv::Ptr<cv::xfeatures2d::SURF> surf = cv::xfeatures2d::SURF::create(400); // Hessian threshold

    std::vector<cv::KeyPoint> keypoints;
    cv::Mat descriptors;

    surf->detectAndCompute(img, cv::noArray(), keypoints, descriptors);

    cv::Mat output;
    cv::drawKeypoints(img, keypoints, output, cv::Scalar::all(-1), cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);

    cv::imshow("SURF", output);
    cv::waitKey(0);
    return 0;
}

特征提取算法比较总结

算法 是否开源 描述子类型 匹配类型 特点
SIFT 浮点(128维) L2(欧氏距离) 稳定性好,适合图像拼接
SURF ❌(专利) 浮点 L2 快速但已过时
ORB 二值(256位) Hamming(汉明) 快速,适合实时系统
AKAZE 二值或浮点 Hamming/L2 稳定性与速度兼顾
BRISK 二值 Hamming 实时性强

小结

  • 推荐优先使用 ORBAKAZE(开源 + 高速);
  • 高精度图像处理可考虑 SIFT
  • 所有算法都可配合 BFMatcherFLANN 进行匹配;
  • 选择依据:速度要求匹配精度是否支持缩放旋转

相关推荐
手握风云-1 小时前
优选算法的寻踪契合:字符串专题
算法
闭着眼睛学算法2 小时前
【华为OD机考正在更新】2025年双机位A卷真题【完全原创题解 | 详细考点分类 | 不断更新题目 | 六种主流语言Py+Java+Cpp+C+Js+Go】
java·c语言·javascript·c++·python·算法·华为od
山烛2 小时前
OpenCV:人脸检测,Haar 级联分类器原理
人工智能·opencv·计算机视觉·人脸检测·harr级联分类器
IT古董2 小时前
【第五章:计算机视觉-项目实战之目标检测实战】2.目标检测实战:中国交通标志检测-(2)中国交通标志检测数据格式转化与读取
算法·目标检测·计算机视觉
MobotStone2 小时前
LLM 采样入门到进阶:理解与实践 Top-K、Top-P、温度控制
算法
杨小码不BUG2 小时前
CSP-J/S初赛知识点精讲-图论
c++·算法·图论··编码·csp-j/s初赛
IT古董3 小时前
【第五章:计算机视觉-项目实战之图像分割实战】1.图像分割理论-(1)图像分割基础知识:定义、任务描述、应用场景、标注格式
yolo·目标检测·计算机视觉
LeaderSheepH4 小时前
常见的排序算法
数据结构·算法·排序算法
吃饭睡觉发paper4 小时前
High precision single-photon object detection via deep neural networks,OE2024
人工智能·目标检测·计算机视觉
周杰伦_Jay5 小时前
【图文详解】强化学习核心框架、数学基础、分类、应用场景
人工智能·科技·算法·机器学习·计算机视觉·分类·数据挖掘