OPENCV(python)--初学之路(十五)Shi-Tomasi 角点检测和追踪的良好特征和SIFT简介

一前言

今天还是挺高兴的,我的原力值在上周排太原市第八,这都是因为大家,感谢!!同时我也希望大家能关注我,我在大学这几年都将致力于视觉学习,有感兴趣的多多关注呐。

二主要内容

Shi-Tomasi 角点检测和追踪的良好特征

理论

在上一章中,我们看到了 Harris 角点检测。 之后在 1994 年,J. Shi 和 C. Tomasi 在他们的论文 Good Features to Track 中做了一个小修改,与 Harris 角点检测相比显示出更好的结果。Harri 角点检测的评分由下式给出:

不同于此,Shi-Tomasi 提出:

如果它大于阈值,则将其视为角点。如果我们像在 Harris 角点检测中那样将它绘制在空间中,将得到如下图像:

从图中可以看出,只有当都大于最小值\时,它才被视为一个角点(绿色区域)。

代码

OpenCV 有一个函数, cv.goodFeaturesToTrack()

cv.goodFeaturesToTrack() 是 OpenCV 中用于检测图像中显著角点(特征点)的函数,基于 Shi-Tomasi 角点检测方法 (也称为 Good Features to Track)。它是 Harris 角点检测的改进版本,提供了更好的角点选择准则。

cv.goodFeaturesToTrack(image, maxCorners, qualityLevel, minDistance, corners=None, mask=None, blockSize=None, useHarrisDetector=None, k=None)

参数说明(其实真正用的时候不用写这么多参数,了解即可)

参数 说明
image 输入图像(单通道,8位或32位浮点型)。
maxCorners 返回的最大角点数量(若 ≤0 表示无限制)。
qualityLevel 角点质量阈值(通常 0.01 到 0.1)。与最佳角点得分的比例,低于该值的角点被拒绝。
minDistance 角点之间的最小欧氏距离。
mask 可选掩码,指定检测区域(mask=0 处不检测)。
blockSize 计算角点响应函数的邻域大小(默认 3)。
useHarrisDetector 是否使用 Harris 角点检测(默认 False 表示使用 Shi-Tomasi 方法)。
k Harris 角点检测的自由参数(仅在 useHarrisDetector=True 时有效)。

注意事项

  1. 输入图像必须是单通道的。

  2. qualityLevel 是根据图像中最大角点响应值进行缩放的。例如,如果最大响应值为 R_max,则所有响应值小于 qualityLevel * R_max 的角点会被丢弃。

  3. minDistance 用于在检测后执行非极大值抑制,确保角点之间保持一定距离。

  4. 如果角点数量超过 maxCorners,则只返回响应最强的那些角点。

它通过 Shi-Tomasi 方法(或 Harris 角点检测,如果你指定它)在图像中找到 N 个最佳的角点。

像往常一样,图像应该是灰度图像。然后指定要查找的角点数量。然后指定质量等级,该等级是 0-1 之间的值,所有低于这个质量等级的角点都将被忽略。最后设置检测到的两个角点之间的最小欧氏距离。

通过所有这些信息,该函数可以在图像中找到角点。所有低于质量等级的角点都将被忽略。然后它根据质量按降序对剩余的角点进行排序。该函数选定质量等级最高的角点(即排序后的第一个角点),忽略该角点最小距离范围内的其余角点,以此类推最后返回 N 个最佳的角点。

以下代码将以25个点举例

python 复制代码
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt

# 读取原始图像文件
img = cv.imread(r'D:\python_code\pic\sumoiao.webp')

# 将彩色图像转换为灰度图像
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)

# 使用Shi-Tomasi算法检测角点
corners = cv.goodFeaturesToTrack(gray, 25, 0.01, 10)
这里的25可更改

# 将角点坐标转换为整数格式
corners = np.int0(corners)

# 遍历所有检测到的角点并在原图上绘制
for i in corners:
    x, y = i.ravel()
    cv.circle(img, (x, y), 3, (0, 255, 0), -1)

# 使用Matplotlib显示处理后的图像
plt.imshow(cv.cvtColor(img, cv.COLOR_BGR2RGB))
plt.axis('off')
plt.show()
 

效果如下

其实效果比哈里斯角好很多,但是感觉依旧不尽人意,所以我将讲解更精确的算法

SIFT 简介(尺度不变特征变换)

理论(太理论,理解即可)

在前几章中,我们看到了一些角点检测器,如 Harris 等。它们具有旋转不变性,这意味着,即使图像旋转,我们也可以找到相同的角点。因为很明显,角点在旋转图像中也是角点。但是缩放呢?如果图像缩放,角点可能就不再是角点。以下图为例,在小图像中使用一个小窗口能够检测出角点,然而将图像放大后,在同一窗口中的图像变得平坦,无法检测出角点。所以 Harris 角点不具有尺度不变性。

因此,在 2004 年,不列颠哥伦比亚大学的 D.Lowe 在他的论文Distinctive Image Features from Scale-Invariant Keypoints 中提出了一种新算法,尺度不变特征变换(SIFT),用以提取特征点并计算其描述子。 (这篇论文易于理解,被认为是关于 SIFT 的最佳材料。以下解释只是该论文的简短摘要)

SIFT 算法主要涉及四个步骤。我们将逐一看到它们。

1.尺度空间极值检测

从上图可以看出,我们不能使用同一个窗口来检测不同尺度空间中的角点。检测小的角点可以用小的窗口,但检测更大的角点则需要更大的窗口。为此需要进行尺度空间滤波。使用不同σ值的高斯拉普拉斯算子(LoG)对图像进行卷积。具有不同σ值的 LoG 可以检测不同大小的斑点。简而言之,σ相当于一个尺度变换因子。例如,在上图中使用具有低σ的高斯核可以检测出小的角点,而具有高σ的高斯核则适合于检测大的角点。因此,我们可以在尺度空间和二维平面中找到局部最大值(x,y,σ)(x,y,σ),这意味着在σ尺度中的(x,y)(x,y)处有一个潜在的特征点。

但是 LoG 的计算量非常大,因此 SIFT 算法使用高斯差分法求取 LoG 的近似值。分别使用方差值为 σ 和 kσ的高斯核对图像进行模糊,对所得的结果再求二者的差值就是 DoG。如下图所示:

找到 DoG 后,搜索不同尺度空间和二维平面中的局部最大值。例如,将图像中的一个像素与其 8 个相邻像素、尺度空间上一层中相邻的 9 个像素以及尺度空间下一层中相邻的 9 个像素做比较。如果该像素值是一个局部最大值,那么它就是一个潜在的特征点。基本上可以说特征点是相应尺度空间的最佳代表。如下图所示:

2.特征点定位

一旦找到潜在的特征点,就必须对其进行细化以获得更准确的结果。论文作者使用尺度空间的泰勒展开来获得更准确的极值位置,如果此极值处的强度小于阈值(0.03),则将其忽略。该阈值在 OpenCV 中被称为contrastThreshold

contrastThreshold 是用于过滤低对比度特征点的阈值。在SIFT算法中:

  1. 作用:过滤掉图像中低对比度的关键点(这些点通常不稳定且容易受噪声影响)

  2. 原理:通过计算DoG(高斯差分)金字塔中极值的对比度值,丢弃对比度低于该阈值的点

  3. 位置 :该阈值在SIFT算法的关键点检测阶段应用

DoG 对边缘更加敏感,因此需要去除边缘。为此,使用了类似于 Harris 角点检测的思路。论文作者使用 2x2 Hessian 矩阵(H)来计算主曲率。我们从 Harris 角点检测得知,当一个特征值大于另一个特征值时检测到的是边界。所以这里论文作者使用了一个简单的函数,如果比率大于阈值则丢弃该特征点,在 OpenCV 中这个比率被称为 edgeThreshold 。论文中给出的边界阈值是 10。

所以,所有低对比度特征点和边缘特征点被去除后,剩下的就是我们所感兴趣的特征点。

3.指定方向

现在,为每个特征点指定方向,以实现图像的旋转不变性。获取特征点所在的尺度空间的领域,并且计算该区域的梯度大小和方向。由此创建了一个包含 36 个 bins(每 10°一个 bin,覆盖了 360°)的方向直方图(由梯度幅度和圆形高斯窗口加权,其中高斯窗口的等于当前特征点尺度空间的 1.5 倍)。采用直方图中的最高峰为主方向,同时也考虑其余任何高于最高峰 80%的峰来计算方向。这就会创建具有位置和尺度空间相同但方向不同的特征点。这样做有助于匹配的稳定性。

4.特征点描述子

现在创建特征点描述子。在关键点周围选取 16x16 的邻域。将它为 16 个 4x4 大小的子块。对于每个子块,创建包含 8 个 bin 的方向直方图。因此总共有 128 个 bin 值可用。由这 128 个形成的向量构成了特征点描述子。除此之外,还采取了一些措施来实现对光照变化、旋转等的鲁棒性。

5.特征点匹配

通过识别两幅图像中距离最近的特征点来进行特征点匹配。但在某些情况下,第二个最接近的匹配可能非常接近第一个,这种情况可能由噪音或其他原因而引起。在这种情况下,计算最近距离与第二最近距离的比率。如果比率大于 0.8,则忽略。根据论文,这样做消除了大约 90%的错误匹配,同时只去除了 5%的正确匹配。

以上是 SIFT 算法的总结。关于更多详细信息和理解,强烈建议阅读原始论文。记住一件事,这个算法受到专利保护,所以这个算法被包含在 opencv contrib repo 中。

OpenCV 中的 SIFT

现在让我们看看 OpenCV 中提供的 SIFT 函数。让我们从特征点检测及绘制开始。首先,我们必须构造一个 SIFT 对象。我们可以使用不同的参数,这不是必须的,关于参数的解释可参考文档。

sift.detect() 函数查找图像中的特征点。如果只想搜索图像的一部分,则可以传递一个掩膜。返回的每个特征点都是一个特殊的结构,它有许多属性,如(x,y)坐标,有意义邻域的大小,指定方向的角度,指定特征点强度的响应等。

OpenCV 还提供 cv.drawKeyPoints() 函数,该函数在特征点的位置上绘制小圆圈。如果您向其传递一个标志 cv.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS ,它将绘制一个特征点大小的圆圈,它甚至会显示其方向。见下面的例子。

cv.drawKeypoints(image, keypoints, outImage, color=None, flags=None)

参数详解

参数 说明
image 输入图像(可以是彩色或灰度图)
keypoints 关键点列表,通常来自 detect()detectAndCompute()
outImage 输出图像(如果为 None,会创建新图像)
color 关键点颜色,默认 (-1, -1, -1) 表示随机颜色
flags 绘制标志,控制绘制样式

代码如下(由于版本更新,sift已经包含在opencv中所以opencv4.4以上的就可直接运行代码)

python 复制代码
import numpy as np
import cv2 as cv
import os

# 禁用Qt的内部MIME警告
os.environ['QT_LOGGING_RULES'] = '*.debug=false;qt.*.warning=false'

# 读取输入图像
img = cv.imread(r'D:\python_code\pic\sumoiao.webp')

# 将图像转换为灰度图
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)

# 创建SIFT检测器对象
sift = cv.SIFT_create()

# 检测图像中的关键点
kp = sift.detect(gray, None)

# 在原始图像上绘制检测到的关键点
img = cv.drawKeypoints(gray, kp, img)

# 显示结果图像
cv.imshow('SIFT Keypoints Result', img)
cv.waitKey(0)
cv.destroyAllWindows()
 

效果如下

三最后一语

今天算是更了很多内容了,挺重要的,挺有意思的。今天大家先学吧,明天可能不会更新,我一周尽量更4-5篇,已经很极限了,快期末周了。

"记住该记住的,忘记该忘记的;改变能改变的,接受不能改变的。"

《麦田里的守望者》| 塞林格

感谢观看,希望关注,共勉!!

相关推荐
龙亘川2 分钟前
《2025 数字孪生白皮书》:智能算法落地实战指南,附技术实现细节
人工智能·智慧城市
时间之里3 分钟前
【图像处理3D】:相机坐标系之间的变换
图像处理·人工智能·3d
AndrewHZ5 分钟前
【图像处理基石】如何高质量地生成一张庆祝元旦的图片?
图像处理·人工智能·opencv·算法·计算机视觉·生成式模型·genai
adjust25865 分钟前
day 46
人工智能·机器学习·numpy
电商API_1800790524711 分钟前
淘宝商品数据爬虫技术实践指南
大数据·数据库·人工智能·爬虫
柠檬071113 分钟前
vector<cv::point2f>如何快速转成opencv mat
人工智能·opencv·计算机视觉
Pyeako13 分钟前
Opencv计算机视觉
人工智能·python·深度学习·opencv·计算机视觉
aopstudio16 分钟前
ASR概念和术语学习指南(2):传统 ASR 系统的工作流程
人工智能·语音识别·asr
雅欣鱼子酱16 分钟前
ECP5702 PD诱骗协议芯片,单芯片取电5V~20V输出给后端充电模板!
网络·人工智能·芯片·电子元器件
司南OpenCompass20 分钟前
司南“六位一体”评测体系的一年演进
人工智能·大模型·多模态模型·大模型评测·司南评测·ai评测