241. 尺度不变特征变换5(SIFT)

13. 特征提取

一、OpenCV 中的 SIFT 类

  • OpenCV 提供了丰富的特征检测算法,而且继承了 cv::Feature2D 类,采用了统一的定义和封装。如:AffineFeature、AgastFeatureDetector、AKAZE、BRISK、FastFeatureDetector、GFTTDetector、KAZE、MSER、ORB、SimpleBlobDetector、SIFT、SURF 等。
    OpenCV 中提供 cv::SIFT 类实现 SIFT方法。cv::SIFT 类继承了 cv::Feature2D 类,通过 create 静态方法创建。

  • SIFT类封装了 SIFT 提取关键点和计算描述符的参数,类的声明在 include/opencv2/ features2d .hpp 文件中。

1、构造 SIFT 对象

  • 在 Python 语言中,OpenCV 提供了 SIFT 类的接口函数 cv.SIFT.create() 实例化 SIFT 类。
cv.SIFT.create([, nfeatures[, nOctaveLayers[, contrastThreshold[, edgeThreshold[, sigma]]]]]) → retval
cv.SIFT.create(nfeatures, nOctaveLayers, contrastThreshold, edgeThreshold, sigma, descriptorType) → retval
cv.SIFT_create([, nfeatures[, nOctaveLayers[, contrastThreshold[, edgeThreshold[, sigma]]]]]) → retval
cv.SIFT_create(nfeatures, nOctaveLayers, contrastThreshold, edgeThreshold, sigma, descriptorType) → retval

参数说明:

  • nfeatures:保留的最佳特征的数量,按算法测度值大小排序
  • nOctaveLayers:每个倍频程的层数,根据图像分辨率自动计算得到
  • contrastThreshold:对比度阈值,用于滤除低对比度的弱特征,默认值 0.04
  • edgeThreshold:用于过滤边缘特征的阈值,默认值 10
  • sigma:高斯模糊系数 σ \sigmaσ 的初值,默认值 1.6
  • descriptorType:描述符的类型,仅支持 CV_32F 和 CV_8U

注意事项:

  • 函数 cv.SIFT.create() 实例化 SIFT 类,构造一个 SIFT 对象。
  • 描述符的类型 descriptorType 仅支持 CV_32F 和 CV_8U
  • 函数 cv.SIFT.getDefaultName 返回字符串的标识符。当对象保存到文件或字符串时,该字符串用作顶级 xml/yml 节点的标记。

2、检测特征点:

sift.detect(image, [, mask]) → keypoints

参数说明:

  • sift:实例化的 SIFT 对象
  • image:输入图像,单通道
  • mask:掩模图像,8 位单通道,指定查找关键点的区域,可选项
  • keypoints :检测到的关键点,是一个特殊的数据结构,包括以下属性:
    • Point2f pt:坐标
    • float size:关键点的邻域直径
    • float angle:关键点的方向,取值为 [0,360)
    • float response:关键点的响应强度
    • int octave:关键点所在的图像金字塔的组
    • int class_id:关键点的 id 编号

3、绘制特征点

cv.drawKeypoint(image, keypoints, outImage[, color[, flags]]) → outImage

参数说明:

  • image:输入图像
  • keypoints:输入图像,单通道
  • outimage:输出图像,
  • color:绘制关键点的颜色
  • flags:绘制关键点特征的选择
    • cv.DRAW_MATCHES_FLAGS_DEFAULT,默认值,对每个关键点仅绘制中心点,不包括围绕关键点的圆和大小、方向
    • cv.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS,对于每个关键点绘制表示关键点大小和方向的圆
    • cv.DRAW_MATCHES_FLAGS_DRAW_OVER_OUTIMG,在输入图像上绘制匹配关系
    • cv.DRAW_MATCHES_FLAGS_NOT_DRAW_SINGLE_POINTS,不绘制单个关键点

4、其它成员函数:

cv.Feature2D.compute(images, keypoints[, descriptors]) → keypoints, descriptors
cv.Feature2D.detect(image[, mask]) → keypoints

cv.Feature2D.detectAndCompute(image, mask[, descriptors[, useProvidedKeypoints]]) → keypoints, descriptors
cv.Feature2D.defaultNorm() → retval
cv.Feature2D.descriptorType() → retval
cv.Feature2D.empty() → retval
cv.Feature2D.getDefaultName() → retval
cv.Feature2D.read(fileName) → None
cv.Feature2D.write(fileName) → None

5、关于专利问题的说明:

  • 由于 SIFT 和 SURF 都是专有和专利算法,在学术研究中可以免费使用的,但在商业应用中需要获得授权许可。
    因此,OpenCV3、OpenCV4 在默认安装中删除了 SIFT 和 SURF 等专利算法,并将其转移到 “OpenCV_contrib” 包中。为了使用 “OpenCV_contrib” 包的算法,在 OpenCV/C++ 中,需要启用 OpenCV contrib 支持,从源代码编译和安装 OpenCV。在 OpenCV/Python 中,需要通过 pip 安装 OpenCV contrib python 包。

  • 但在 OpenCV3/Python 的一些版本中,由于 OpenCV 用 OPENCV_ENABLE_NONFREE 对编译进行了限制,使用 SIFT 和 SURF 算法时仍然会出现错误:
    "module ‘cv2.cv2’ has no attribute ‘xfeatures2d’ ”
    或者:
    cv2.error: OpenCV(3.4.8) C:\projects\opencv-python\opencv_contrib\modules\xfeatures2d\src\sift.cpp: 1207: error: (-213:The function/feature is not implemented) This algorithm is patented and is excluded in this configuration; Set OPENCV_ENABLE_NONFREE CMake option and rebuild the library in function ‘cv::xfeatures2d::SIFT::create’
    卸载之前的 OpenCV 和包,将 OpenCV 版本退到 3.4.2 即可解决。

  • 2020年,由于 SIFT 专利到期, OpenCV 4.4 已经将 SIFT 移到主库,可以正常使用。

资料

youcans_的博客:
https://blog.csdn.net/youcans/article/details/126018654
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容