一、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