在 Python 中使用 OpenCV 筛选
特征提取是图像处理和机器学习中不可或缺的过程。 它是指通过提取有价值的信息位将原始数据转换为信息。
在图像处理中,我们找到有效的关键点及其描述符。
在 Python 中,我们使用 OpenCV 库来处理和操作图像。 我们可以使用这个库应用不同的技术和预定义的算法。
本教程将演示如何使用 OpenCV 实现 SIFT 算法并将其用于 Python 中的特征匹配。 我们还将学习在 Python 中使用 OpenCV 使用 SIFT 算法来匹配两个图像。
用于特征提取的SIFT算法
SIFT(尺度不变特征变换)是一种复杂而有用的特征提取技术。 它克服了其他算法的旋转变化或比例变化的问题,这意味着如果图像旋转或缩放到不同的大小,提取的信息可能会发生变化。
SIFT 算法通过提取有效的关键点及其描述符来避免这一切。 它是尺度和旋转不变的。
我们已经讨论过特征提取。 现在让我们讨论用于特征提取的 SIFT 算法所涉及的步骤。
总共有五个阶段。
尺度空间极值检测
第一阶段称为尺度空间极值检测。
正如所讨论的,我们需要在每个尺度上都存在的特征。 对于更大的尺度,我们需要更大的窗口。
此阶段涉及使用不同的缩放参数并计算高斯差分,即具有不同缩放参数值的高斯模糊的差异。 它将使用给定的缩放值选择一个坐标,并检查它是否存在具有更高和更低缩放值的坐标。
关键点定位
现在让我们进入第二阶段,即关键点定位。 该阶段将筛选出选定的关键点。
它将使用泰勒级数扩展来获得更精细的关键点并找到它们的强度。 如果强度小于指定的阈值,则拒绝。
方向分配
下一阶段称为方向分配。 正如所讨论的,关键点是旋转不变的,这个阶段确保相同。
它将使用关键点的周围区域来计算梯度及其方向。 创建了 36 个 bin 并绘制在直方图上以表示 360 度,高于 80% 的峰值被视为新关键点并用于确定所选关键点的方向。
关键点描述符
第四阶段旨在通过将与关键点相邻的 16x16 块分成 16 个 4x4 块来创建关键点描述符。 为包含 8 个 bin 的每个块构造方向直方图。
所有这些值都表示为关键点描述符向量。
关键点匹配
最后阶段涉及关键点匹配。 它通过寻找邻居来匹配两个关键点。
这用于消除错误匹配。
现在我们已经详细讨论了 SIFT 算法。 让我们看看如何使用 Python 的 OpenCV 库来实现它。
使用 SIFT 类在 Python 中使用 OpenCV 实现 SIFT
SIFT_create()
构造函数对象可用于创建可从图像中检测关键点的 SIFT 类对象。
我们可以指定不同的参数,尽管每个参数都有一些默认值。 参数是:nfeatures、nOctaveLayers、contrastThreshold、edgeThreshold、sigma 和 descriptorType。
nfeatures 参数可以指定要从结果中选择的最佳特征的数量。 可以使用 nOctaveLayers 参数指定每个八度音阶中的层,其默认值为 3。
contrastThreshold 和 edgeThreshold 值过滤掉弱的和类似边缘的特征。 Gaussian的sigma使用sigma参数指定,对于软镜头点击的图片可以调低。
最后一个参数指定描述符的类型,可以是 CV_32F 或 CV_8U。
让我们看看如何使用这个方法。
import numpy as np
import cv2 as cv
i = cv.imread('obj.png')
g = cv.cvtColor(i,cv.COLOR_BGR2GRAY)
sift_ob = cv.SIFT_create()
kp = sift_ob.detect(g,None)
img = cv.drawKeypoints(g,kp,i)
cv.imshow('Output', img)
cv.waitKey(0)
cv.destroyAllWindows()
输出:
让我们试着理解上面的例子。
我们使用 imread()
函数读取图像。 然后,我们使用可以改变任何图像颜色空间的 cvtColor 方法将该图像转换为灰度。
该算法适用于灰度图像。
我们使用具有默认值的 SIFT_create()
函数创建了一个对象。 我们对创建的对象使用 detect()
函数来识别给定图像中的点; 它返回一个存储结果的元组。
我们使用 drawKeypoints()
函数在图像上绘制关键点以获得更好的视觉表示。 我们在此函数中传递元组和图像。
使用 imshow()
函数显示最终图像。
waitKey()
函数阻止输出窗口自动关闭,等待用户按下某个键。 我们使用 destroyAllWindows()
函数关闭了窗口。
SIFT 较早存在于 OpenCV Contrib 库中,并在 2020 年专利到期时添加到 OpenCV。它在 OpenCV 3.4.2.16 版本中不再可用。
现在让我们讨论如何通过在 Python 中使用 OpenCV 实现 SIFT 算法来匹配两个图像。
通过在 Python 中使用 OpenCV 实现 SIFT 算法来匹配两个图像
如上所述,我们可以使用 SIFT 算法检测各种关键点和描述符。 为此,我们可以使用蛮力匹配器。
蛮力匹配器将一次获取一个关键点及其描述符,并尝试将其与另一幅图像的一组特征进行匹配,返回最接近的匹配。
因此,我们将使用 BFMatcher()
构造函数创建一个 Brute-Force 匹配器对象。 该对象接受两个参数。
第一个参数是 normType 参数,它是使用的距离。 对于基于字符串的,我们应该使用 NORM_HAMMING,但对于我们的案例 (SIFT),我们可以使用 NORM_L1 或 NORM_l2。
第二个参数是 crossCheck,如果设置为 True,将只返回任一集合中的相应匹配项。 创建BFMatcher对象后,我们可以使用 match()
函数传递两组描述符进行匹配。
在此之后,我们可以使用 drawMatches()
函数在两个图像上绘制相应的匹配项。 图像并排放置,匹配的关键点使用一条线连接。
每条线都有一个独特的颜色来标识特征。 让我们看一个这样的例子。
我们将匹配以下两张 Qutub Minar 图像的特征。
Image 1:
Image 2:
代码:
import cv2
import matplotlib.pyplot as plt
%matplotlib inline
i1 = cv2.imread('q3.jpeg')
i2 = cv2.imread('q4.jpeg')
img1 = cv2.cvtColor(i1, cv2.COLOR_BGR2GRAY)
img2 = cv2.cvtColor(i2, cv2.COLOR_BGR2GRAY)
sift = cv2.SIFT_create()
k_1, des_1 = sift.detectAndCompute(img1,None)
k_2, des_2 = sift.detectAndCompute(img2,None)
bf = cv2.BFMatcher(cv2.NORM_L1, crossCheck=True)
matches = bf.match(des_1,des_2)
matches = sorted(matches, key = lambda x:x.distance)
img3 = cv2.drawMatches(img1, k_1, img2, k_2, matches[:50], img2, flags=2)
cv2.imshow('Output', img3)
cv2.waitKey(0)
cv2.destroyAllWindows()
输出:
在上面的例子中,我们使用 SIFT 算法和 Brute-Force 匹配器匹配了两个图像的特征。
首先,我们使用 SIFT 算法提取了两幅图像的特征。 然后我们使用 Brute-Force 匹配器对象匹配这些特征。
使用 drawMatches()
函数在两个图像上绘制结果匹配。
总结
本教程演示了在 Python 中使用 OpenCV 实现用于特征提取的 SIFT 算法。 详细讨论了 SIFT 算法背后的理论,并强调了它相对于其他技术的优势。
详细介绍了该算法的五个阶段。 这些是尺度空间极值检测、关键点定位、方向分配、关键点描述符和关键点匹配。
我们讨论了通过使用 SIFT_create()
对象创建 SIFT 类的对象来实现此技术。 我们突出显示了此类中 detect()
方法的使用,并使用 drawKeypoints()
函数绘制了关键点。
我们还讨论了在 Python 中使用 OpenCV 使用 SIFT 算法匹配两个图像。 为此,首先,我们使用SIFT算法提取特征; 然后,我们创建了一个 Brute-Force 匹配器的对象。
我们将描述符传递给对象的 match()
属性以查找匹配项。 使用 drawMatches()
函数在两个图像上绘制结果以提供视觉表示。
相关文章
Pandas DataFrame DataFrame.shift() 函数
发布时间:2024/04/24 浏览次数:133 分类:Python
-
DataFrame.shift() 函数是将 DataFrame 的索引按指定的周期数进行移位。
Python pandas.pivot_table() 函数
发布时间:2024/04/24 浏览次数:82 分类:Python
-
Python Pandas pivot_table()函数通过对数据进行汇总,避免了数据的重复。
Pandas read_csv()函数
发布时间:2024/04/24 浏览次数:254 分类:Python
-
Pandas read_csv()函数将指定的逗号分隔值(csv)文件读取到 DataFrame 中。
Pandas 多列合并
发布时间:2024/04/24 浏览次数:628 分类:Python
-
本教程介绍了如何在 Pandas 中使用 DataFrame.merge()方法合并两个 DataFrames。
Pandas loc vs iloc
发布时间:2024/04/24 浏览次数:837 分类:Python
-
本教程介绍了如何使用 Python 中的 loc 和 iloc 从 Pandas DataFrame 中过滤数据。
在 Python 中将 Pandas 系列的日期时间转换为字符串
发布时间:2024/04/24 浏览次数:894 分类:Python
-
了解如何在 Python 中将 Pandas 系列日期时间转换为字符串