OpenCV 例程 300篇256. 特征检测之 CenSurE(StarDetector)算法

Posted YouCans

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenCV 例程 300篇256. 特征检测之 CenSurE(StarDetector)算法相关的知识,希望对你有一定的参考价值。

『youcans 的 OpenCV 例程300篇 - 总目录』


【youcans 的 OpenCV 例程 300篇】256. 特征检测之 CenSurE(StarDetector)算法


6.9.1 算法简介

中心环绕算法(Center Surround Extremas, CenSurE)是 Agrawal M 等于 2008年提出的关键点检测算法,具有尺度不变性,计算效率高,特征点坐标精确,性能良好,可以实时实现。

SIFT 和 SURF算法都是利用 Hessian 矩阵的行列式作为检测判据。Harris 和 Hessian 本质上是角探测器,善于在某个尺度上检测定位,但在尺度变化时并不稳健。而拉普拉斯算子在不同尺度上的最大值可以获取特征尺度,一些算法选择设计更高效的拉普拉斯梯度(LoG)模板,SIFT 算法中使用 DoG 近似 LoG,SURF 使用 Box 近似高斯梯度模板(以DoB代替DoG),CenSurE 则使用环形函数的梯度模板,DART 使用分片三角函数模板。

在 CenSurE 算法中,在所有位置和所有尺度计算简化的中心环绕滤波器,并在局部邻域中找到极值。

Agrawal 文中设计了如图的 4种环形梯度滤波器模板,圆形核近似 LoG 的性能最好,但计算复杂度太高。其它3种滤波器都可以使用积分图像快速计算,其中方形核 boxes 的计算效率最高,但其旋转不变性也最差;八边形的性能最好,计算速度也较快。

中心环绕算法 CenSurE 的重要特点是不构造图像金字塔,而是用不同尺度的检测器对原始图像进行检测,就可以检测出不同尺度的关键点。将圆形 BLoG中的内外圆替换为内外正方形,构造 CenSurE_DoB,产生基本的中心环绕 Haar 小波。

CenSurE 算法使用 7个尺度递增的检测器构建尺度空间 n=[1, 2, 3, 4, 5, 6, 7]。对应于不同尺度 n 的 CenSurE_DoB 滤波器的内外正方形的边长分别为 2 ∗ n + 1 2*n+1 2n+1 4 ∗ n + 1 4*n+1 4n+1。检测特征的最小尺度对应于边长为 2 的方块,相当于 σ = 1.885 \\sigma=1.885 σ=1.885 的 LoG检测器。这 5个不同的检测尺度覆盖了 2.5 个倍频程,而且可以很容易地扩展到更大的检测尺度范围。

CenSurE_DoB 滤波器可以使用倾斜积分图实现快速计算,即旋转45度的像素值积分图像:
t i t l e d ( X , Y ) = ∑ y < Y , a b s ( x − X + 1 ) ≤ Y − y − 1 i m a g e ( x , y ) titled(X, Y) = \\sum_y<Y,abs(x-X+1)\\le Y-y-1image(x,y) titled(X,Y)=y<Y,abs(xX+1)Yy1image(x,y)
CenSurE 特征检测由三个步骤组成:

(1)使用倾斜积分图像,计算近似高斯差分(以DoB代替DoG);

(2)采用非极大值抑制,检测局部极大值;

(3)基于 Harris 边缘滤波器,剔除边缘上的不稳定特征点。

CenSurE 特征可以直接使用 SURF 描述符,而 MU-SURF 描述符的性能更好。


6.9.2 OpenCV 中的 cv::StarDetector 类

OpenCV 中实现的 CenSurE 算法称为 STAR 算法,对 CenSurE 算法进行了一些改进。

(1)STAR 滤波器的形状是两个交错重叠的正方形,构成一个八角形。

(2)STAR 算法选择 17个尺度递增的检测器 n=[1, 2, 3, 4, 6, 8, 11, 12, 16, 23, 32, 45, 46, 64, 90, 128],构成 17个不同尺寸的八角形,按下表形成 12个不同尺寸的滤波器。

尺度123456789101112
外核尺寸246812162232466490128
内核尺寸023468111623324564

(3)滤波器的卷积运算基于积分图像,但没有直接计算八角形内地灰度和,而是分别用积分图像和双倾斜积分图像分别计算后相加。

OpenCV 中提供 cv::StarDetector 类实现 CenSurE算法,StarDetector 类继承了cv::Feature2D类,通过create静态方法创建。

StarDetector 类的构造函数为:

static Ptr<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)
static Ptr<StarDetector> cv::xfeatures2d::StarDetector::create(int maxSize = 45, int responseThreshold = 30, int lineThresholdProjected = 10, int lineThresholdBinarized = 8,
int suppressNonmaxSize = 5)

在 Python 语言中,OpenCV 提供了接口函数 cv.xfeatures2d.StarDetector.create, 实例化 StarDetector 类。

cv.xfeatures2d.StarDetector.create(	[, maxSize=45, responseThreshold=30, lineThresholdProjected=10, lineThresholdBinarized=8, suppressNonmaxSize=5]	) → retval
cv.xfeatures2d.StarDetector_create(	[, maxSize=45, responseThreshold=30, lineThresholdProjected=10, lineThresholdBinarized=8, suppressNonmaxSize=5]	) → retval
star.detect(image[, mask]) → keypoints

参数说明:

  • maxSize:使用滤波器的最大尺寸,默认值为 45,可选值为 4, 6, 8, 11, 12, 16, 23, 32, 45, 46, 64, 90, 128
  • responseThreshold:非最大值抑制中的阈值,默认值为 30
  • lineThresholdProjected:直线抑制中的阈值,默认值为 10
  • lineThresholdBinarized:直线抑制中尺寸矩阵的阈值,默认值为 8
  • suppressNonmaxSize:非极大值抑制的邻域范围,默认值为 5
  • image:输入图像,单通道。
  • mask:掩模图像,指定查找关键点的区域,可选项。
  • keypoints:检测到的关键点,元组。
  • descriptors:关键点的描述符,形为(nfeatures,32)的Numpy数组。

注意事项:

  • ⑴ 通过接口函数cv.xfeatures2d.StarDetector.create或cv.xfeatures2d.StarDetector_create实例化StarDetector类,在OpenCV的不同版本中可能只允许其中一种方式。

  • ⑵ OpenCV 中的StarDetector类是特征点检测算法,并不涉及特征描述符的构造,因此不能使用Feature2D类中的compute、detectAndCompute等计算特征描述符的成员函数。


例程 14.28:特征检测之 STAR 算法

# 14.28 特征检测之 StarDetector 算子
    # 读取基准图像
    imgRef = cv.imread("../images/Circuit04.png", flags=1)  # (480, 600, 3)
    refer = cv.cvtColor(imgRef, cv.COLOR_BGR2GRAY)  # 基准图像
    height, width = imgRef.shape[:2]  # 图片的高度和宽度
    print("shape of image: ", height, width)  # 480 600
    # 读取或构造目标图像
    top, left = int(0.1*height), int(0.1*width)
    border = cv.copyMakeBorder(imgRef, top, top, left, top, borderType=cv.BORDER_CONSTANT, value=(32,32,32))
    zoom = cv.resize(border, (width, height), interpolation=cv.INTER_AREA)
    theta= 10  # 顺时针旋转角度,单位为角度
    x0, y0 = width//2, height//2  # 以图像中心作为旋转中心
    MAR = cv.getRotationMatrix2D((x0,y0), theta, 1.0)
    imgObj = cv.warpAffine(zoom, MAR, (width, height))  # 旋转变换,默认为黑色填充
    # imgObj = cv.imread("../images/Circuit04B.png", flags=1)  # (480, 600, 3)
    object = cv.cvtColor(imgObj, cv.COLOR_BGR2GRAY)  # 目标图像
    print("shape of image: ", imgObj.shape)  # (480, 600, 3)

    # STAR 关键点检测
    star = cv.xfeatures2d.StarDetector_create()  # STAR 特征检测
    brief = cv.xfeatures2d.BriefDescriptorExtractor_create()  # BRIEF 特征描述
    kpStarRef = star.detect(imgRef, None)  # STAR 基准图像关键点检测
    kpStarObj = star.detect(imgObj, None)  # STAR 目标图像关键点检测
    # BRIEF 特征描述
    kpStarRef, desBriefRef = brief.compute(imgRef, kpStarRef)  # 通过 BRIEF 计算描述子
    kpStarObj, desBriefObj = brief.compute(imgObj, kpStarObj)  # 通过 BRIEF 计算描述子

    # 特征点匹配,Brute-force matcher
    matcher = cv.BFMatcher()  # 构造 BFmatcher 对象
    matches = matcher.match(desBriefRef, desBriefObj)  # 对描述子 des1, des2 进行匹配
    matches = sorted(matches, key=lambda x: x.distance)
    matches1 = cv.drawMatches(imgRef, kpStarRef, imgObj, kpStarObj, matches[:100], None, flags=2)
    print('queryIdx=%d' % matches[0].queryIdx)
    print('trainIdx=%d' % matches[0].trainIdx)
    print('distance=%d' % matches[0].distance)
    print("bf.match:".format(len(matches)))

    imgRefStar = cv.drawKeypoints(imgRef, kpStarRef, None, flags=cv.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)  # 绘制关键点大小和方向
    imgObjStar = cv.drawKeypoints(imgObj, kpStarObj, None, flags=cv.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)  # 绘制关键点大小和方向
    print(desBriefRef.shape, desBriefObj.shape)

    plt.figure(figsize=(9, 6))
    ax1 = plt.subplot(212)
    ax1.set_title("Star detector & Brief descriptor")
    plt.imshow(cv.cvtColor(matches1, cv.COLOR_BGR2RGB)), plt.axis('off')
    ax2 = plt.subplot(221)
    plt.axis('off'), plt.imshow(cv.cvtColor(imgRefStar, cv.COLOR_BGR2RGB))
    ax2.set_title("Star keypoints (Ref)")
    ax3 = plt.subplot(222)
    plt.axis('off'), plt.imshow(cv.cvtColor(imgObjStar, cv.COLOR_BGR2RGB))
    ax3.set_title("Star keypoints (Obj)")
    plt.tight_layout()
    plt.show()

程序说明
程序运行结果如图所示。


参考文献: Motilal Agrawal, Kurt Konolige, and Morten Rufus Blas. Censure: Center surround extremas for realtime feature detection and matching. In Computer Vision–ECCV 2008, pages 102–115. Springer, 2008.

【本节完】

版权声明:
youcans@xupt 原创作品,转载必须标注原文链接:(https://blog.csdn.net/youcans/article/details/128565226)
Copyright 2023 youcans, XUPT
Crated:2023-01-05

以上是关于OpenCV 例程 300篇256. 特征检测之 CenSurE(StarDetector)算法的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV 例程 300篇246. 特征检测之ORB算法

OpenCV 例程 300篇246. 特征检测之ORB算法

OpenCV 例程 300篇243. 特征检测之 FAST 算法

OpenCV 例程 300篇243. 特征检测之 FAST 算法

OpenCV 例程 300篇243. 特征检测之 FAST 算法

OpenCV 例程 300篇245. 特征检测之 BRISK 算子