传统CV算法——角点特征点提取匹配算法实战
harris角点
- 角点可以是两个边缘的角点;
- 角点是邻域内具有两个主方向的特征点;
- 角点通常被定义为两条边的交点,更严格的说,角点的局部邻域应该具有两个不同区域的不同方向的边界。或者说,角点就是多条轮廓线之间的交点。
- 像素点附近区域像素无论是在梯度方向、还是在梯度幅值上都发生较大的变化。
- 一阶导数(即灰度的梯度)的局部最大所对应的像素点;
- 两条及两条以上边缘的交点;
- 图像中梯度值和梯度方向的变化速率都很高的点;
- 角点处的一阶导数最大,二阶导数为零,指示物体边缘变化不连续的方向。
- 角点在任意一个方向上做微小移动,都会引起该区域的梯度图的方向和幅值发生很大变化。
- 具有旋转不变形,但是不具备尺度不变性。
算法步骤
- 求x,y两个方向梯度,并计算出矩阵M
- 对矩阵M计算特征值、行列式和迹
- 根据特征值的关系并使用阈值确定图像特征
R = det M − k ( trace M ) 2 R=\operatorname{det} M-k(\operatorname{trace} M)^2 R=detM−k(traceM)2
λ 1 \lambda 1 λ1 :X轴方向的偏导的特征值;
λ 2 : Y \lambda 2: Y λ2:Y 轴方向的偏导的特征值;
- det M : \operatorname{det} M: detM: 矩阵行列式, λ 1 + λ 2 \lambda_1+\lambda_2 λ1+λ2
- traceM:矩阵的迹, λ 1 λ 2 \lambda_1 \lambda_2 λ1λ2
- k k k : Harri系数, 一般取值为 0.04 ∼ 0.06 0.04 \sim 0.06 0.04∼0.06
函数api
CV_EXPORTS_W void cornerHarris( InputArray src, OutputArray dst, int blockSize,int ksize, double k,int borderType = BORDER_DEFAULT );
dst:Harri算法的输出矩阵(输出图像),CV_32FC1类型,与src有同样的尺寸
src:输入图像,单通道,8位或浮点型
blockSize:邻域大小
ksize:Sobel算子的孔径大小
k:Harri算法系数
import cv2
import numpy as npimg = cv2.imread("./images/32.jpg")img2gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)img2gray = np.float32(img2gray)dst = cv2.cornerHarris(img2gray,blockSize=2,ksize=3,k=0.02)dst = cv2.dilate(dst,cv2.getStructuringElement(cv2.MORPH_RECT,ksize=(8,8)))img[dst>0.01*dst.max()] = [0,0,255]cv2.imshow("dst",img)
cv2.waitKey(0)
托马斯算法
- 原理:Harris 角点检测中每个窗口的分数公式是将矩阵 M M M 的行列式与 M M M 的迹相减:
R = λ 1 λ 2 − k ( λ 1 + λ 2 ) 2 R=\lambda_1 \lambda_2-k\left(\lambda_1+\lambda_2\right)^2 R=λ1λ2−k(λ1+λ2)2
- 由于 Harris 角点检测算法的稳定性和 k 值有关,而 k 是个经验值,不好设定最佳值。
Shi-Tomasi 发现,角点的稳定性其实和矩阵 M M M 的较小特征值有关,于是直接用较小的那个特征值作为分数。这样就不用调整k值了。所以 Shi-Tomasi 将分数公式改为如下形式:
R = min ( λ 1 , λ 2 ) R=\min \left(\lambda_1, \lambda_2\right) R=min(λ1,λ2)
cv2.goodFeaturesToTrack
是 OpenCV 中用于检测图像中角点(特征点)的函数,它通常用于光流法跟踪中的初始点检测。这个函数基于 Shi-Tomasi 角点检测算法,在给定的图像中找到一些“好”的特征点。以下是该函数的主要输入参数及其作用:
函数原型
cv2.goodFeaturesToTrack(image, maxCorners, qualityLevel, minDistance[, corners[, mask[, blockSize[, useHarrisDetector[, k]]]]])
输入参数
-
image (
np.ndarray
):- 描述:输入图像,必须是单通道的灰度图像。
- 作用:在该图像中寻找角点。
-
maxCorners (
int
):- 描述:检测到的角点的最大数量。
- 作用:该参数指定了要返回的角点数量的上限。如果图像中的强角点数量超过了这个值,只会返回最强的前
maxCorners
个角点。如果设置为 0,表示不限制角点数量。
-
qualityLevel (
float
):- 描述:角点质量水平。
- 作用:这是一个相对值,表示角点被接受的最低质量水平。一般取值在 0 到 1 之间。例如,
0.01
表示仅接受最大响应值的 1%。这个参数控制了检测到的角点的最低质量。
-
minDistance (
float
):- 描述:最小欧氏距离。
- 作用:检测到的角点之间的最小距离。如果检测到的角点之间的距离小于此值,则会保留响应更强的角点,删除响应较弱的角点。这可以避免检测到过于接近的角点。
-
corners (
np.ndarray
, 可选):- 描述:输出角点的列表。
- 作用:如果提供了这个参数,函数会将检测到的角点坐标存入这个数组中。
-
mask (
np.ndarray
, 可选):- 描述:操作掩膜。
- 作用:用于指定感兴趣区域。只有掩膜中非零的像素对应的区域才会被检测角点。如果不需要掩膜,可以设置为
None
。
-
blockSize (
int
, 可选):- 描述:邻域大小。
- 作用:角点检测时考虑的邻域大小。通常设置为 3 或 5,即表示使用 3x3 或 5x5 的邻域来计算每个像素点的角点质量。
-
useHarrisDetector (
bool
, 可选):- 描述:是否使用 Harris 角点检测。
- 作用:如果设置为
True
,则使用 Harris 角点检测的方式来测量角点响应。如果设置为False
,则使用 Shi-Tomasi 角点检测方法。默认值为False
。
-
k (
float
, 可选):- 描述:Harris 检测器的自由参数。
- 作用:只有在
useHarrisDetector=True
时,该参数才有效。它是 Harris 角点检测中的自由参数,通常介于 0.04 到 0.06 之间。
返回值
- corners (
np.ndarray
):- 该函数返回检测到的角点的坐标。每个角点的坐标是一个二维数组
[x, y]
。返回的数组形状为(numCorners, 1, 2)
,其中numCorners
是检测到的角点数。
- 该函数返回检测到的角点的坐标。每个角点的坐标是一个二维数组
示例代码
import cv2
import numpy as np# 读取图像并转换为灰度图
img = cv2.imread('image.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 检测角点
corners = cv2.goodFeaturesToTrack(gray, maxCorners=100, qualityLevel=0.01, minDistance=10)# 绘制角点
for i in corners:x, y = i.ravel()cv2.circle(img, (x, y), 3, 255, -1)cv2.imshow('Corners', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.goodFeaturesToTrack
是一个非常实用的函数,广泛应用于特征点检测和跟踪任务中。通过调整输入参数,您可以根据具体应用场景找到最合适的角点集合。
import cv2
import numpy as npimg = cv2.imread("./images/32.jpg")img2gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)img2gray = np.float32(img2gray)# dst = cv2.cornerHarris(img2gray,blockSize=2,ksize=3,k=0.02)
corners = cv2.goodFeaturesToTrack(img2gray,100,0.01,10)
# dst = cv2.dilate(dst,cv2.getStructuringElement(cv2.MORPH_RECT,ksize=(8,8)))# img[dst>0.01*dst.max()] = [0,0,255]
corners = np.int0(corners)for i in corners:x,y = i.ravel()cv2.circle(img,(x,y),radius=3,color=255,thickness=3)cv2.imshow("dst",img)
cv2.waitKey(0)
fast 算法
- 点与周围的值比较,阈值确定。
FAST(Features from Accelerated Segment Test)算法简介
FAST(Features from Accelerated Segment Test)是一种快速特征点检测算法,广泛用于实时计算机视觉任务中,如图像配准、SLAM、目标跟踪等。FAST 算法通过检测图像中具有显著变化的像素点(角点)来找到特征。它的主要优势是计算速度快且易于实现,特别适合需要实时处理的应用。
FAST 算法原理
-
圆形邻域检测:FAST 算法围绕一个中心像素以半径为 3 的圆形邻域(共 16 个像素)进行检测。
-
快速测试:根据一个阈值(称为
threshold
),比较中心像素的强度与邻域像素的强度:- 如果某个像素值显著亮于或暗于中心像素,则认为它是一个潜在的特征点。
-
连续像素检测:如果在圆形邻域上存在至少
N
个连续的像素都满足上述条件(亮于或暗于中心像素),则判定该像素为特征点。 -
非极大值抑制(Non-Maximum Suppression):为提高特征点的定位精度,通常会对检测到的特征点进行非极大值抑制,保留最强的特征点。
cv2.FastFeatureDetector_create
输入参数
cv2.FastFeatureDetector_create()
是 OpenCV 中创建 FAST 特征检测器的函数,它允许用户根据需要配置不同的检测参数。以下是该函数的主要输入参数:
-
threshold (
int
):- 描述:特征点检测的阈值。这个值用于决定一个像素点是否被认为是特征点。阈值越高,检测到的特征点越少。
- 作用:通过调整
threshold
,可以控制算法对特征点的敏感度。
-
nonmaxSuppression (
bool
):- 描述:是否启用非极大值抑制。默认情况下,FAST 会检测很多相邻的特征点,非极大值抑制可以去除相邻特征点中响应较弱的点。
- 作用:启用时,可以提高特征点的定位精度,并减少重复特征点。
-
type (
cv2.FastFeatureDetector_TYPE
):- 描述:指定 FAST 算法的类型。目前支持三种类型:
cv2.FAST_FEATURE_DETECTOR_TYPE_5_8
:使用 8 个连续像素来检测特征点。cv2.FAST_FEATURE_DETECTOR_TYPE_7_12
:使用 12 个连续像素来检测特征点。cv2.FAST_FEATURE_DETECTOR_TYPE_9_16
:使用 16 个连续像素来检测特征点。
- 作用:选择不同类型的 FAST 算法可以适应不同的图像细节和速度需求。
- 描述:指定 FAST 算法的类型。目前支持三种类型:
FAST 算法是一种快速且高效的特征点检测方法,适合实时性要求较高的任务。cv2.FastFeatureDetector_create
提供了灵活的配置选项,通过调整参数,可以有效控制检测的特征点数量和精度。
import cv2src = cv2.imread("33.jpg")
grayImg = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)fast = cv2.FastFeatureDetector_create(threshold=35)
# fast.setNonmaxSuppression(False)
kp = fast.detect(grayImg, None)
img2 = cv2.drawKeypoints(src, kp, None, (0, 0, 255), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)print('Threshold: ', fast.getThreshold())
print('nonmaxSuppression: ', fast.getNonmaxSuppression())
print('neighborhood: ', fast.getType())
print('Total Keypoints with nonmaxSuppression: ', len(kp))
#
cv2.imshow('fast_true', img2)
#
# fast.setNonmaxSuppression(False)
# kp = fast.detect(grayImg, None)
#
# print('Total Keypoints without nonmaxSuppression: ', len(kp))
#
# img3 = cv2.drawKeypoints(src, kp, None, (0, 0, 255), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)# cv2.imshow('fast_false', img3)cv2.waitKey()
- fast_true
- fast_false NMS关闭
import cv2src = cv2.imread("./images/33.jpg")
grayImg = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)fast = cv2.FastFeatureDetector_create(threshold=35)
# fast.setNonmaxSuppression(False)
kp = fast.detect(grayImg, None)
img2 = cv2.drawKeypoints(src, kp, None, (0, 0, 255), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)print('Threshold: ', fast.getThreshold())
print('nonmaxSuppression: ', fast.getNonmaxSuppression())
print('neighborhood: ', fast.getType())
print('Total Keypoints with nonmaxSuppression: ', len(kp))
#
cv2.imshow('fast_true', img2)
#
fast.setNonmaxSuppression(False)
kp = fast.detect(grayImg, None)print('Total Keypoints without nonmaxSuppression: ', len(kp))img3 = cv2.drawKeypoints(src, kp, None, (0, 0, 255), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)cv2.imshow('fast_false', img3)cv2.waitKey()
ORB算法
- 常用,略菜sift,但是快
- fast还要快
ORB(Oriented FAST and Rotated BRIEF)算法简介
ORB(Oriented FAST and Rotated BRIEF)是一种用于特征检测和描述的算法,结合了 FAST 角点检测和 BRIEF 描述符,经过改进后适合于图像匹配、物体识别和图像拼接等任务。ORB 是一种开源的替代 SIFT(Scale-Invariant Feature Transform)和 SURF(Speeded-Up Robust Features)的方法,它既快又不受专利限制。
ORB 算法的原理
-
特征检测:
- 使用 FAST(Features from Accelerated Segment Test)算法进行角点检测。
- 为了增加旋转不变性,ORB 使用 Harris 响应函数来筛选和排序特征点。
-
方向分配:
- 计算特征点邻域的方向,通过中心像素的方向分布给每个特征点分配一个方向。
-
特征描述:
- 使用 BRIEF(Binary Robust Independent Elementary Features)描述符来描述特征点。
- 为了增加旋转不变性,ORB 通过对 BRIEF 的特征进行旋转处理,使得描述符具有旋转不变性。
-
特征点匹配:
- ORB 使用汉明距离(Hamming Distance)进行二进制描述符的快速匹配。
cv2.ORB_create
输入参数
cv2.ORB_create()
是 OpenCV 中创建 ORB 特征检测器和描述符提取器的函数。它允许用户根据需要配置不同的检测和描述参数。以下是该函数的主要输入参数:
-
nfeatures (
int
, 默认值500
):- 描述:要检测的特征点的最大数量。
- 作用:通过调整这个值可以控制检测到的特征点数量,较大的值会增加计算时间但能检测更多特征点。
-
scaleFactor (
float
, 默认值1.2
):- 描述:图像金字塔每层之间的尺度因子。
- 作用:这个参数影响了尺度空间的构建,每一层特征点的检测是基于对原始图像进行尺度缩放的结果。默认值
1.2
意味着每一层图像缩小 1.2 倍。
-
nlevels (
int
, 默认值8
):- 描述:金字塔的层数。
- 作用:影响 ORB 在不同尺度下检测特征点的能力。层数越多,算法可以检测到更多不同尺度的特征点。
-
edgeThreshold (
int
, 默认值31
):- 描述:边界阈值。
- 作用:这个参数决定了特征检测过程中图像边缘忽略的像素大小,以避免检测到不完整的角点。
-
firstLevel (
int
, 默认值0
):- 描述:金字塔的第一级。
- 作用:设置金字塔的起始层。通常从第 0 层开始。
-
WTA_K (
int
, 默认值2
):- 描述:每次比较 BRIEF 描述符的点对数量。
- 作用:该参数可以是 2、3 或 4,数值越大意味着描述符的辨识度更高。
-
scoreType (
cv2.ORB_HARRIS_SCORE
orcv2.ORB_FAST_SCORE
, 默认值cv2.ORB_HARRIS_SCORE
):- 描述:特征点排序的方法。
- 作用:
cv2.ORB_HARRIS_SCORE
使用 Harris 响应值进行排序。cv2.ORB_FAST_SCORE
使用 FAST 响应值进行排序。
-
patchSize (
int
, 默认值31
):- 描述:计算方向和 BRIEF 描述符的补丁大小。
- 作用:补丁大小越大,算法的抗噪能力越强。
-
fastThreshold (
int
, 默认值20
):- 描述:FAST 角点检测的阈值。
- 作用:调整这个参数可以改变 ORB 算法对角点的敏感度。
示例代码
ORB 是一种高效、快速的特征检测和描述算法,适用于实时计算机视觉任务。cv2.ORB_create
提供了多种配置选项,通过调整参数,可以根据应用需求检测和描述图像中的特征点。ORB 的特点是计算速度快且不受专利限制,是许多计算机视觉任务的理想选择。
import cv2
import numpy as npimg = cv2.imread("./images/33.jpg")img2gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)orb = cv2.ORB_create()
kp = orb.detect(img2gray,None)
kp,des = orb.compute(img2gray,kp)img2 = cv2.drawKeypoints(img,kp,None,color=(0,0,255),flags=0)cv2.imshow("dst",img2)
cv2.waitKey(0)
sift 算法
- 加了大小匹配,解决了尺度不变形
- 专利算法,慎用
SIFT(Scale-Invariant Feature Transform)算法简介
SIFT(Scale-Invariant Feature Transform)是一种经典的特征检测和描述算法,由 David Lowe 在 1999 年提出。它能够检测图像中的特征点(关键点)并生成具有尺度和旋转不变性的描述符,广泛应用于图像匹配、物体识别、图像拼接、三维重建等计算机视觉任务。
SIFT 算法的原理
-
尺度空间极值检测:
- 通过在不同尺度下对图像进行高斯模糊并构建高斯金字塔(Gaussian Pyramid),在图像尺度空间中检测关键点。
- 使用差分高斯(Difference of Gaussian, DoG)来近似拉普拉斯算子,找到图像在空间和尺度上变化最显著的点(关键点)。
-
关键点精确定位:
- 对检测到的关键点进行亚像素精确定位,去除低对比度的关键点和边缘响应点,以提高关键点的稳定性和鲁棒性。
-
方向分配:
- 根据关键点的局部梯度方向分布,为每个关键点分配一个或多个方向,确保特征的旋转不变性。
-
关键点描述符生成:
- 在每个关键点的方向对齐的局部邻域内,计算多个方向梯度直方图(Histogram of Oriented Gradients, HOG),生成具有 128 维特征向量的描述符。
-
特征点匹配:
- 通过欧氏距离(或其他距离度量)匹配两个图像中的 SIFT 描述符,实现图像之间的特征点匹配。
cv2.SIFT_create()
输入参数
cv2.SIFT_create()
是 OpenCV 中创建 SIFT 特征检测器和描述符提取器的函数,用户可以根据需要调整多个参数来控制特征检测和描述符生成的过程。以下是该函数的主要输入参数及其含义:
-
nfeatures (
int
, 默认值0
):- 描述:要保留的关键点的最大数量。
- 作用:该参数控制算法保留的关键点数量。默认情况下检测所有特征点。
-
nOctaveLayers (
int
, 默认值3
):- 描述:每组(Octave)中的层数(层间的图像数量)。
- 作用:每个组中的层数越多,检测的关键点越多,描述符的计算也会更加详细。通常使用默认值
3
。
-
contrastThreshold (
float
, 默认值0.04
):- 描述:对比度阈值,用于过滤掉低对比度的特征点。
- 作用:这个参数影响检测到的特征点的数量,值越大,特征点越少且更稳定,值越小则可以检测到更多细节特征点,但可能会有更多噪声。
-
edgeThreshold (
float
, 默认值10
):- 描述:边缘阈值,用于过滤掉位于边缘上的特征点。
- 作用:较低的值会导致检测到的特征点数减少,较高的值会检测到更多的特征点。调整该参数可以改善检测到的特征点的质量。
-
sigma (
float
, 默认值1.6
):- 描述:高斯模糊的标准差。
- 作用:用于在高斯金字塔中生成尺度空间时的初始模糊程度。较高的值使得算法在更高尺度上检测特征点,较低的值可以检测到更多细节特征点。
SIFT 是一种经典且非常有效的特征检测和描述算法,具有很强的尺度和旋转不变性,能够在许多复杂的视觉任务中表现出色。cv2.SIFT_create()
函数提供了多种参数来调节特征点检测和描述符生成的过程,通过合理调整这些参数,用户可以在不同的应用场景中获得最佳效果。
import cv2src = cv2.imread("./images/33.jpg")
grayImg = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)sift = cv2.SIFT_create()kp = sift.detect(grayImg,None)img = cv2.drawKeypoints(src,kp,None,color=(0,0,255))cv2.imshow("img",img)
cv2.waitKey()
SURF算法
-
比sift快
-
现有专利保护,需要重新编译,或者换OpenCV版本
SURF(Speeded-Up Robust Features)算法简介
SURF(Speeded-Up Robust Features)是 SIFT 的加速版本,由 Bay et al. 在 2006 年提出。SURF 算法通过对 SIFT 进行优化,提高了计算速度,同时在特征检测和描述符生成方面保持了较高的精度和稳定性。SURF 在图像识别、对象跟踪、图像配准和三维重建等计算机视觉任务中广泛应用。
SURF 算法的原理
-
积分图像(Integral Image):
- 使用积分图像来快速计算不同尺度下的卷积操作,这是 SURF 提高计算效率的关键步骤。
-
Hessian 矩阵行列式:
- SURF 使用 Hessian 矩阵的行列式来检测图像中的特征点。Hessian 矩阵反映了图像在某点的二阶导数信息,能有效检测出角点和斜率变化显著的区域。
-
方向分配:
- 在特征点的局部邻域内,SURF 计算梯度信息并通过加权直方图分配一个主方向,使得特征具有旋转不变性。
-
特征描述符:
- 在主方向的基础上,SURF 通过对特征点邻域内的梯度信息进行编码,生成 64 维或 128 维的描述符。SURF 的描述符与 SIFT 类似,但通过使用 Haar 小波响应加速了计算过程。
-
快速匹配:
- SURF 描述符可以通过欧氏距离或汉明距离进行快速匹配,适用于实时计算机视觉任务。
cv2.xfeatures2d.SURF_create()
输入参数
cv2.xfeatures2d.SURF_create()
是 OpenCV 中创建 SURF 特征检测器和描述符提取器的函数。以下是该函数的主要输入参数及其含义:
-
hessianThreshold (
float
, 默认值100
):- 描述:Hessian 矩阵行列式的阈值。
- 作用:该阈值控制了检测到的关键点数量,值越高检测到的关键点越少且更稳定,值越低则会检测到更多的特征点。通常在实际应用中需要根据图像内容和需求调整该参数。
-
nOctaves (
int
, 默认值4
):- 描述:金字塔的层数(Octave 的数量)。
- 作用:每个 Octave 是尺度空间的一层,层数越多可以检测到的特征点尺度范围越广,但计算开销也会增加。
-
nOctaveLayers (
int
, 默认值3
):- 描述:每个 Octave 中的层数。
- 作用:控制在每个尺度空间层中的图像采样数,层数越多可以检测到更多细节特征。
-
extended (
bool
, 默认值True
):- 描述:控制描述符的维度。
- 作用:如果为
True
,生成的描述符为 128 维;如果为False
,生成的描述符为 64 维。128 维描述符虽然更加精确,但计算量也更大。
-
upright (
bool
, 默认值False
):- 描述:是否使用不考虑方向的描述符。
- 作用:如果为
True
,SURF 生成的描述符不考虑方向信息,从而不具备旋转不变性。这种设置下,算法速度更快,但只能用于不需要旋转不变性的场景。
SURF 算法通过对 SIFT 的优化,极大地提高了特征检测和描述符生成的速度,同时在许多应用场景中保持了较高的精度。cv2.xfeatures2d.SURF_create()
提供了多个参数来调节特征检测器的行为,用户可以根据具体需求灵活调整这些参数,以在速度和精度之间取得平衡。
import cv2src = cv2.imread("./images/33.jpg")
grayImg = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)surf= cv2.xfeatures2d.SURF_create()kp = surf.detect(grayImg,None)img = cv2.drawKeypoints(src,kp,None,color=(0,0,255))cv2.imshow("img",img)
cv2.waitKey()
匹配算法
import cv2img1 = cv2.imread("./images/34.jpg")
grayImage1= cv2.cvtColor(img1,cv2.COLOR_BGR2GRAY)
img2 = cv2.imread("./images/33.jpg")
grayImage2= cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)orb = cv2.ORB_create()kp1, des1 = orb.detectAndCompute(grayImage1, None)
kp2, des2 = orb.detectAndCompute(grayImage2, None)bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
matches = bf.match(des1, des2)
matches = sorted(matches, key=lambda x: x.distance)img3 = cv2.drawMatches(img1, kp1, img2, kp2, matches[:10], None, flags=2)cv2.imshow("img",img3)
cv2.waitKey(0

grayImg1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
img2 = cv2.imread('./images/33.jpg')
grayImg2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)detector = cv2.xfeatures2d.SIFT_create()kp1, des1 = detector.detectAndCompute(grayImg1, None)
kp2, des2 = detector.detectAndCompute(grayImg2, None)matcher = cv2.DescriptorMatcher_create(cv2.DescriptorMatcher_FLANNBASED)
matches = matcher.knnMatch(des1, des2, k=2)
matchesMask = [[0, 0] for i in range(len(matches))]for i, (m, n) in enumerate(matches):if m.distance < 0.7 * n.distance:matchesMask[i] = [1, 0]draw_params = dict(matchColor=(0, 255, 0), singlePointColor=(255, 0, 0), matchesMask=matchesMask, flags=0)
img3 = cv2.drawMatchesKnn(img1, kp1, img2, kp2, matches, None, **draw_params)cv2.imshow("img", img3)
cv2.waitKey(0)
相关文章:

传统CV算法——角点特征点提取匹配算法实战
harris角点 角点可以是两个边缘的角点;角点是邻域内具有两个主方向的特征点;角点通常被定义为两条边的交点,更严格的说,角点的局部邻域应该具有两个不同区域的不同方向的边界。或者说,角点就是多条轮廓线之间的交点。…...
小米电视使用adb 卸载自带应用教程
小米电视使用ADB(Android Debug Bridge)卸载自带应用的教程如下。请注意,在操作过程中请确保谨慎行事,避免误删系统关键应用导致电视无法正常使用。 准备工作 下载ADB工具: 在电脑上下载ADB工具。ADB是Android Debug …...

编译FFmpeg动态库
编译FFmpeg动态库 环境 macOS High SierraFFmpeg 4.3android-ndk-r21b 编译so库 下载FFmpeg4.3源代码,进入源码目录创建build_android.sh脚本,ffmpeg从4.0起新增了target-osandroid,所以不用再修改configure文件。 注意: ndk…...
yum的基本使用方法
yum(全称 "Yellow dog Updater Modified")是基于RPM包管理器的软件包管理系统,主要用于Fedora和Red Hat系列的Linux发行版中。它允许用户安装、更新、删除以及搜索软件包,并能自动处理软件包之间的依赖关系。下面是一些…...

Nginx+Keepalive集群实战
随着Nginx在国内的发展潮流,越来越多的互联网公司都在使用Nginx,Nginx高性能、稳定性成为IT人士青睐的HTTP和反向代理服务器。 Nginx负载均衡一般位于整个网站架构的最前端或者中间层,如果为最前端时单台Nginx会存在单点故障,也就…...

[数据集][目标检测]街道乱放广告牌检测数据集VOC+YOLO格式114张1类别
数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):114 标注数量(xml文件个数):114 标注数量(txt文件个数):114 标注类别…...

腾讯云的免费ssl证书过期后不占用免费额度
我申请了三张免费证书,两张过期了,已使用的数量还是1,说明已过期的不占免费额度,这样的话,只要每三个月重新申请就能一直用免费证书了。 下证很快,第一张一分钟以内,第二张大概5分钟左右。 原来…...
MySQL学习(DDL,DML,DQL)基本语法总结
DDL 使用某个数据库 use world;展示表 show tables;创建表 create table student(id int,name varchar(10),age int,gender varchar(10));删除表 drop table student; 修改表结构 查看表结构 desc student;添加列 alter table student add dept varchar(10);修改列名和类型…...
JAVA学习-练习试用Java实现“单词反转”
问题: 随便输出一个字符串 String str "45abc,defg"; 里面含有 abc,de,fg 三个单词 怎么处理能让单词反转,其他顺序不变呢 输出 “45cba,edgf”; 解答思路: 以下是使用 Java 实现的单词反转程序:…...

【MySQL】深圳大学数据库实验一
目录 一、实验目的 二、实验要求 三、实验设备 四、建议的实验步骤 4.1 使用SQL语句创建如上两张关系表 4.2 EXERCISES. 1 SIMPLE COMMANDS 4.3 EXERCISES 2 JOINS 4.4 EXERCISES 3 FUNCTIONS 4.5 EXERCISES 4 DATES 五、实验总结 5.1 数据库定义语言(DDL…...

接口测试 —— 如何设计高效的测试用例!
摘要: 随着互联网应用的日益复杂化,接口测试已成为保证软件质量不可或缺的一部分。本文将探讨如何有效地设计接口测试用例,并提供实用的建议和示例。 一、引言 接口测试(API测试)是确保系统各部分之间交互正确性的关键…...

linux top命令介绍以及使用
文章目录 介绍 top 命令1. top 的基本功能2. 如何启动 top3. top 的输出解释系统概况任务和 CPU 使用情况内存和交换空间进程信息 4. 常用操作 总结查看逻辑CPU的个数查看系统运行时间 介绍 top 命令 top 是一个在类 Unix 系统中广泛使用的命令行工具,用于实时显示…...

必备资源!精选大模型领域100篇必读论文,赶紧加入收藏夹!
本文主要为当前大模型领域热门研究方向(如文生图、文生视频、文生音乐等)的热门论文。希望能够为大家提供较为全面的大模型最新研究进展。当然,目前还无法涵盖所有热门论文以及研究方向,望请见谅。 以下,为2024年2月份…...
基于STM32设计的防盗书包(华为云IOT)(216)
文章目录 一、前言1.1 项目介绍【1】开发背景【2】项目实现的功能【3】项目硬件模块组成1.2 设计思路【1】整体设计思路【2】整体构架【3】上位机开发思路1.3 项目开发背景【1】选题的意义【2】可行性分析【3】参考文献【4】摘要【5】项目背景1.4 开发工具的选择【1】设备端开发…...

2024高教社杯全国大学生数学建模竞赛C题原创python代码
2024高教社杯全国大学生数学建模竞赛C题原创python代码 C题题目:农作物的种植策略 思路可以参考我主页之前的文章 以下均为python代码,推荐用anaconda中的notebook当作编译环境 from gurobipy import Model import pandas as pd import gurobipy as g…...

Java基础 - 14 - Java高级技术
一.单元测试 就是针对最小的功能单元(方法),编写测试代码对其进行正确性测试 1.1 Junit单元测试框架 可以用来对方法进行测试,它是第三方公司开源出来的(很多开发工具已经集成了Junit框架,如IDEAÿ…...

glsl着色器学习(六)
准备工作已经做完,下面开始渲染 gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);gl.clearColor(0.5, 0.7, 1.0, 1.0); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);gl.enable(gl.DEPTH_TEST); gl.enable(gl.CULL_FACE);设置视口 gl.viewport(0,…...

毒枸杞事件启示录:EasyCVR视频AI智能监管方案如何重塑食品卫生安全防线
一、方案背景 近年来,食品安全问题频发,引发了社会各界的广泛关注。其中,毒枸杞事件尤为引人关注。新闻报道,在青海格尔木、甘肃靖远等地,部分商户为了提升枸杞的品相,违规使用焦亚硫酸钠和工业硫磺进行“…...
git进阶·团队开发的时候为何要创建临时分支来修复bug
若在团队开发中,突然遇到一个功能性bug,你会怎么使用git来管理分支呢? 在近些年来,团队工作的经验中,我总结出来的是,最好是先创建一个临时分支来修复bug,修复好后,再合并到主分支或…...

Unity 性能优化工具收集
本文地址:https://blog.csdn.net/t163361/article/details/141809415 Unity原始工具 UPR 官方 UPR UPR桌面端解决方案,减轻测试设备性能压力,使测试过程更加顺畅。提供CLI用于自动化测试系统对接。 PerformanceBenchmarkReporter Unity 性…...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...

【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...
可靠性+灵活性:电力载波技术在楼宇自控中的核心价值
可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...
蓝桥杯 2024 15届国赛 A组 儿童节快乐
P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡,轻快的音乐在耳边持续回荡,小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下,六一来了。 今天是六一儿童节,小蓝老师为了让大家在节…...

12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...

HashMap中的put方法执行流程(流程图)
1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中,其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下: 初始判断与哈希计算: 首先,putVal 方法会检查当前的 table(也就…...

Linux 内存管理实战精讲:核心原理与面试常考点全解析
Linux 内存管理实战精讲:核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用,还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...

Rust 开发环境搭建
环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行: rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu 2、Hello World fn main() { println…...

QT开发技术【ffmpeg + QAudioOutput】音乐播放器
一、 介绍 使用ffmpeg 4.2.2 在数字化浪潮席卷全球的当下,音视频内容犹如璀璨繁星,点亮了人们的生活与工作。从短视频平台上令人捧腹的搞笑视频,到在线课堂中知识渊博的专家授课,再到影视平台上扣人心弦的高清大片,音…...

链式法则中 复合函数的推导路径 多变量“信息传递路径”
非常好,我们将之前关于偏导数链式法则中不能“约掉”偏导符号的问题,统一使用 二重复合函数: z f ( u ( x , y ) , v ( x , y ) ) \boxed{z f(u(x,y),\ v(x,y))} zf(u(x,y), v(x,y)) 来全面说明。我们会展示其全微分形式(偏导…...