OpenCV从入门到精通——角点特征点提取匹配算法实战

news2024/11/11 6:58:51

harris角点

  • 角点可以是两个边缘的角点;
  • 角点是邻域内具有两个主方向的特征点;
  • 角点通常被定义为两条边的交点,更严格的说,角点的局部邻域应该具有两个不同区域的不同方向的边界。或者说,角点就是多条轮廓线之间的交点。
  • 像素点附近区域像素无论是在梯度方向、还是在梯度幅值上都发生较大的变化。
  • 一阶导数(即灰度的梯度)的局部最大所对应的像素点;
  • 两条及两条以上边缘的交点;
  • 图像中梯度值和梯度方向的变化速率都很高的点;
  • 角点处的一阶导数最大,二阶导数为零,指示物体边缘变化不连续的方向。
  • 角点在任意一个方向上做微小移动,都会引起该区域的梯度图的方向和幅值发生很大变化。
  • 具有旋转不变形,但是不具备尺度不变性。

算法步骤

- 求x,y两个方向梯度,并计算出矩阵M
- 对矩阵M计算特征值、行列式和迹
- 根据特征值的关系并使用阈值确定图像特征

R = det ⁡ M − k ( trace ⁡ M ) 2 R=\operatorname{det} M-k(\operatorname{trace} M)^2 R=detMk(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.040.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 np

img = 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λ2k(λ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]]]]])

输入参数

  1. image (np.ndarray):

    • 描述:输入图像,必须是单通道的灰度图像。
    • 作用:在该图像中寻找角点。
  2. maxCorners (int):

    • 描述:检测到的角点的最大数量。
    • 作用:该参数指定了要返回的角点数量的上限。如果图像中的强角点数量超过了这个值,只会返回最强的前 maxCorners 个角点。如果设置为 0,表示不限制角点数量。
  3. qualityLevel (float):

    • 描述:角点质量水平。
    • 作用:这是一个相对值,表示角点被接受的最低质量水平。一般取值在 0 到 1 之间。例如,0.01 表示仅接受最大响应值的 1%。这个参数控制了检测到的角点的最低质量。
  4. minDistance (float):

    • 描述:最小欧氏距离。
    • 作用:检测到的角点之间的最小距离。如果检测到的角点之间的距离小于此值,则会保留响应更强的角点,删除响应较弱的角点。这可以避免检测到过于接近的角点。
  5. corners (np.ndarray, 可选):

    • 描述:输出角点的列表。
    • 作用:如果提供了这个参数,函数会将检测到的角点坐标存入这个数组中。
  6. mask (np.ndarray, 可选):

    • 描述:操作掩膜。
    • 作用:用于指定感兴趣区域。只有掩膜中非零的像素对应的区域才会被检测角点。如果不需要掩膜,可以设置为 None
  7. blockSize (int, 可选):

    • 描述:邻域大小。
    • 作用:角点检测时考虑的邻域大小。通常设置为 3 或 5,即表示使用 3x3 或 5x5 的邻域来计算每个像素点的角点质量。
  8. useHarrisDetector (bool, 可选):

    • 描述:是否使用 Harris 角点检测。
    • 作用:如果设置为 True,则使用 Harris 角点检测的方式来测量角点响应。如果设置为 False,则使用 Shi-Tomasi 角点检测方法。默认值为 False
  9. 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 np

img = 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 算法原理
  1. 圆形邻域检测:FAST 算法围绕一个中心像素以半径为 3 的圆形邻域(共 16 个像素)进行检测。

  2. 快速测试:根据一个阈值(称为 threshold),比较中心像素的强度与邻域像素的强度:

    • 如果某个像素值显著亮于或暗于中心像素,则认为它是一个潜在的特征点。
  3. 连续像素检测:如果在圆形邻域上存在至少 N 个连续的像素都满足上述条件(亮于或暗于中心像素),则判定该像素为特征点。

  4. 非极大值抑制(Non-Maximum Suppression):为提高特征点的定位精度,通常会对检测到的特征点进行非极大值抑制,保留最强的特征点。

cv2.FastFeatureDetector_create 输入参数

cv2.FastFeatureDetector_create() 是 OpenCV 中创建 FAST 特征检测器的函数,它允许用户根据需要配置不同的检测参数。以下是该函数的主要输入参数:

  1. threshold (int):

    • 描述:特征点检测的阈值。这个值用于决定一个像素点是否被认为是特征点。阈值越高,检测到的特征点越少。
    • 作用:通过调整 threshold,可以控制算法对特征点的敏感度。
  2. nonmaxSuppression (bool):

    • 描述:是否启用非极大值抑制。默认情况下,FAST 会检测很多相邻的特征点,非极大值抑制可以去除相邻特征点中响应较弱的点。
    • 作用:启用时,可以提高特征点的定位精度,并减少重复特征点。
  3. 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 算法是一种快速且高效的特征点检测方法,适合实时性要求较高的任务。cv2.FastFeatureDetector_create 提供了灵活的配置选项,通过调整参数,可以有效控制检测的特征点数量和精度。

import cv2

src = 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 cv2

src = 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 算法的原理
  1. 特征检测

    • 使用 FAST(Features from Accelerated Segment Test)算法进行角点检测。
    • 为了增加旋转不变性,ORB 使用 Harris 响应函数来筛选和排序特征点。
  2. 方向分配

    • 计算特征点邻域的方向,通过中心像素的方向分布给每个特征点分配一个方向。
  3. 特征描述

    • 使用 BRIEF(Binary Robust Independent Elementary Features)描述符来描述特征点。
    • 为了增加旋转不变性,ORB 通过对 BRIEF 的特征进行旋转处理,使得描述符具有旋转不变性。
  4. 特征点匹配

    • ORB 使用汉明距离(Hamming Distance)进行二进制描述符的快速匹配。

cv2.ORB_create 输入参数

cv2.ORB_create() 是 OpenCV 中创建 ORB 特征检测器和描述符提取器的函数。它允许用户根据需要配置不同的检测和描述参数。以下是该函数的主要输入参数:

  1. nfeatures (int, 默认值 500):

    • 描述:要检测的特征点的最大数量。
    • 作用:通过调整这个值可以控制检测到的特征点数量,较大的值会增加计算时间但能检测更多特征点。
  2. scaleFactor (float, 默认值 1.2):

    • 描述:图像金字塔每层之间的尺度因子。
    • 作用:这个参数影响了尺度空间的构建,每一层特征点的检测是基于对原始图像进行尺度缩放的结果。默认值 1.2 意味着每一层图像缩小 1.2 倍。
  3. nlevels (int, 默认值 8):

    • 描述:金字塔的层数。
    • 作用:影响 ORB 在不同尺度下检测特征点的能力。层数越多,算法可以检测到更多不同尺度的特征点。
  4. edgeThreshold (int, 默认值 31):

    • 描述:边界阈值。
    • 作用:这个参数决定了特征检测过程中图像边缘忽略的像素大小,以避免检测到不完整的角点。
  5. firstLevel (int, 默认值 0):

    • 描述:金字塔的第一级。
    • 作用:设置金字塔的起始层。通常从第 0 层开始。
  6. WTA_K (int, 默认值 2):

    • 描述:每次比较 BRIEF 描述符的点对数量。
    • 作用:该参数可以是 2、3 或 4,数值越大意味着描述符的辨识度更高。
  7. scoreType (cv2.ORB_HARRIS_SCORE or cv2.ORB_FAST_SCORE, 默认值 cv2.ORB_HARRIS_SCORE):

    • 描述:特征点排序的方法。
    • 作用
      • cv2.ORB_HARRIS_SCORE 使用 Harris 响应值进行排序。
      • cv2.ORB_FAST_SCORE 使用 FAST 响应值进行排序。
  8. patchSize (int, 默认值 31):

    • 描述:计算方向和 BRIEF 描述符的补丁大小。
    • 作用:补丁大小越大,算法的抗噪能力越强。
  9. fastThreshold (int, 默认值 20):

    • 描述:FAST 角点检测的阈值。
    • 作用:调整这个参数可以改变 ORB 算法对角点的敏感度。

示例代码

ORB 是一种高效、快速的特征检测和描述算法,适用于实时计算机视觉任务。cv2.ORB_create 提供了多种配置选项,通过调整参数,可以根据应用需求检测和描述图像中的特征点。ORB 的特点是计算速度快且不受专利限制,是许多计算机视觉任务的理想选择。


import cv2
import numpy as np

img = 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 算法的原理
  1. 尺度空间极值检测

    • 通过在不同尺度下对图像进行高斯模糊并构建高斯金字塔(Gaussian Pyramid),在图像尺度空间中检测关键点。
    • 使用差分高斯(Difference of Gaussian, DoG)来近似拉普拉斯算子,找到图像在空间和尺度上变化最显著的点(关键点)。
  2. 关键点精确定位

    • 对检测到的关键点进行亚像素精确定位,去除低对比度的关键点和边缘响应点,以提高关键点的稳定性和鲁棒性。
  3. 方向分配

    • 根据关键点的局部梯度方向分布,为每个关键点分配一个或多个方向,确保特征的旋转不变性。
  4. 关键点描述符生成

    • 在每个关键点的方向对齐的局部邻域内,计算多个方向梯度直方图(Histogram of Oriented Gradients, HOG),生成具有 128 维特征向量的描述符。
  5. 特征点匹配

    • 通过欧氏距离(或其他距离度量)匹配两个图像中的 SIFT 描述符,实现图像之间的特征点匹配。

cv2.SIFT_create() 输入参数

cv2.SIFT_create() 是 OpenCV 中创建 SIFT 特征检测器和描述符提取器的函数,用户可以根据需要调整多个参数来控制特征检测和描述符生成的过程。以下是该函数的主要输入参数及其含义:

  1. nfeatures (int, 默认值 0):

    • 描述:要保留的关键点的最大数量。
    • 作用:该参数控制算法保留的关键点数量。默认情况下检测所有特征点。
  2. nOctaveLayers (int, 默认值 3):

    • 描述:每组(Octave)中的层数(层间的图像数量)。
    • 作用:每个组中的层数越多,检测的关键点越多,描述符的计算也会更加详细。通常使用默认值 3
  3. contrastThreshold (float, 默认值 0.04):

    • 描述:对比度阈值,用于过滤掉低对比度的特征点。
    • 作用:这个参数影响检测到的特征点的数量,值越大,特征点越少且更稳定,值越小则可以检测到更多细节特征点,但可能会有更多噪声。
  4. edgeThreshold (float, 默认值 10):

    • 描述:边缘阈值,用于过滤掉位于边缘上的特征点。
    • 作用:较低的值会导致检测到的特征点数减少,较高的值会检测到更多的特征点。调整该参数可以改善检测到的特征点的质量。
  5. sigma (float, 默认值 1.6):

    • 描述:高斯模糊的标准差。
    • 作用:用于在高斯金字塔中生成尺度空间时的初始模糊程度。较高的值使得算法在更高尺度上检测特征点,较低的值可以检测到更多细节特征点。

SIFT 是一种经典且非常有效的特征检测和描述算法,具有很强的尺度和旋转不变性,能够在许多复杂的视觉任务中表现出色。cv2.SIFT_create() 函数提供了多种参数来调节特征点检测和描述符生成的过程,通过合理调整这些参数,用户可以在不同的应用场景中获得最佳效果。

import cv2

src = 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 算法的原理
  1. 积分图像(Integral Image)

    • 使用积分图像来快速计算不同尺度下的卷积操作,这是 SURF 提高计算效率的关键步骤。
  2. Hessian 矩阵行列式

    • SURF 使用 Hessian 矩阵的行列式来检测图像中的特征点。Hessian 矩阵反映了图像在某点的二阶导数信息,能有效检测出角点和斜率变化显著的区域。
  3. 方向分配

    • 在特征点的局部邻域内,SURF 计算梯度信息并通过加权直方图分配一个主方向,使得特征具有旋转不变性。
  4. 特征描述符

    • 在主方向的基础上,SURF 通过对特征点邻域内的梯度信息进行编码,生成 64 维或 128 维的描述符。SURF 的描述符与 SIFT 类似,但通过使用 Haar 小波响应加速了计算过程。
  5. 快速匹配

    • SURF 描述符可以通过欧氏距离或汉明距离进行快速匹配,适用于实时计算机视觉任务。

cv2.xfeatures2d.SURF_create() 输入参数

cv2.xfeatures2d.SURF_create() 是 OpenCV 中创建 SURF 特征检测器和描述符提取器的函数。以下是该函数的主要输入参数及其含义:

  1. hessianThreshold (float, 默认值 100):

    • 描述:Hessian 矩阵行列式的阈值。
    • 作用:该阈值控制了检测到的关键点数量,值越高检测到的关键点越少且更稳定,值越低则会检测到更多的特征点。通常在实际应用中需要根据图像内容和需求调整该参数。
  2. nOctaves (int, 默认值 4):

    • 描述:金字塔的层数(Octave 的数量)。
    • 作用:每个 Octave 是尺度空间的一层,层数越多可以检测到的特征点尺度范围越广,但计算开销也会增加。
  3. nOctaveLayers (int, 默认值 3):

    • 描述:每个 Octave 中的层数。
    • 作用:控制在每个尺度空间层中的图像采样数,层数越多可以检测到更多细节特征。
  4. extended (bool, 默认值 True):

    • 描述:控制描述符的维度。
    • 作用:如果为 True,生成的描述符为 128 维;如果为 False,生成的描述符为 64 维。128 维描述符虽然更加精确,但计算量也更大。
  5. upright (bool, 默认值 False):

    • 描述:是否使用不考虑方向的描述符。
    • 作用:如果为 True,SURF 生成的描述符不考虑方向信息,从而不具备旋转不变性。这种设置下,算法速度更快,但只能用于不需要旋转不变性的场景。

SURF 算法通过对 SIFT 的优化,极大地提高了特征检测和描述符生成的速度,同时在许多应用场景中保持了较高的精度。cv2.xfeatures2d.SURF_create() 提供了多个参数来调节特征检测器的行为,用户可以根据具体需求灵活调整这些参数,以在速度和精度之间取得平衡。

import cv2

src = 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 cv2

img1 = 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


![在这里插入图片描述](https://img-blog.csdnimg.cn/img_convert/1f7e2c34445cc8de306e9c4db05ac3d7.png

在这里插入图片描述

  • KD树匹配
import cv2

img1 = cv2.imread('./images/34.jpg')
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)


在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2103121.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

完善补环境框架 bx_et 分析

声明: 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01; 有相关问题请第一时间头像私信联系我…

win10 +git配置+学习笔记

git简介&#xff1a;git是一个分布式版本控制软件&#xff0c;用于有效、高速地处理从小到大的项目版本管理。 安装git&#xff1a;从官网Git (git-scm.com)下载安装包 配置git&#xff1a; git config --global user.name "Your Name" git config --global user.e…

Android 11 (R)AMS Activity内部机制

一、AMS是如何被管理的 如我们在Android 11(R)启动流程中介绍的一样&#xff0c;AMS和ATMS是在SystemServer中被启动的 ActivityTaskManagerService atm mSystemServiceManager.startService(ActivityTaskManagerService.Lifecycle.class).getService(); mActivityManagerSe…

10、Django Admin修改标题

admin from django.contrib import admin from .models import Category, Origin, Hero, Villain # 添加以下代码 admin.site.site_header "系统管理" admin.site.site_title "管理员界面" admin.site.index_title "欢迎来到这里&#xff…

嵌入式:Keil调试时,Memory窗口的更新时机

相关阅读嵌入式https://blog.csdn.net/weixin_45791458/category_12768532.html?spm1001.2014.3001.5482 在Keil中调试程序时&#xff0c;Memory窗口是一个很有用的工具&#xff08;它们由调试器厂商提供并嵌入IDE&#xff09;&#xff0c;可以实时显示存储器中的数据值&#…

gcc编译与Linux下的库

gcc与g编译 GCC&#xff1a;GCC是一个由GNU项目开发的多平台编译器&#xff0c;最初是为C语言设计的编译器&#xff0c;但随着时间的发展&#xff0c;它已经扩展到支持多种编程语言。它支持多种编程语言&#xff0c;包括C、C、Objective-C、Fortran、Ada和Go等。GCC是自由软件&…

linux文件的拓展属性

一、概述 文件的扩展属性&#xff08;EA&#xff09; 即以名称-值对形式将任意元数据与文件 i 节点关联 起来的技术。 2. EA 可用于实现访问列表&#xff08;第 17 章&#xff09;和文件能力&#xff08;第 39 章&#xff09;。 二、EA 命名空间 EA 的命名格式为 namespace…

C++重载实现Mystring

#include<iostream> #include<cstring> //可以使用string类 #include<string> //#include <string.h>using namespace std;class Mystring {public:Mystring():str(nullptr), len(0){}Mystring(const char *const str1){if (str1){len s…

Datawhale X 李宏毅苹果书AI夏令营 学习笔记

学习日志 日期&#xff1a; 2024年9月3日 今日学习内容&#xff1a; 今天&#xff0c;我深入学习了深度学习中的几种重要概念&#xff0c;包括优化算法、特征归一化、以及批量归一化的原理和应用。这次学习的内容涵盖了从基础的梯度下降法到更高级的优化技术&#xff0c;同时…

【Linux系统编程】TCP实现--socket

使用套接字socket实现服务器和客户端之间的TCP通信。 流程如下&#xff1a; 实现代码&#xff1a; /* server.c */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <arpa/inet.h> #include <s…

分类预测|基于麻雀优化正则化极限学习机的数据分类预测Matlab程序SSA-RELM 多特征输入多类别输出

分类预测|基于麻雀优化正则化极限学习机的数据分类预测Matlab程序SSA-RELM 多特征输入多类别输出 文章目录 一、基本原理1. 数据准备2. RELM模型建立3. SSA优化RELM参数4. 模型训练5. 模型评估6. 结果分析与应用原理总结 二、实验结果三、核心代码四、代码获取五、总结 分类预测…

在Ubuntu上运行QtCreator相关程序

背景&#xff1a;希望尝试在Linux系统上跑一下使用QtCreator相关的程序&#xff0c;因为有一些工作岗位要求有Linux上使用Qt的经验。 (1)我是把Windows上的程序移过来的&#xff0c;Windows上文件名称是不区分大小写的。 而Ubuntu上是区分的 所以一部分头文件需要进行修改&am…

大数据Flink(一百一十二):Flink SQL作业快速入门

文章目录 Flink SQL作业快速入门 一、进入Flink开发平台 二、​​​​​​​创建作业 三、​​​​​​​​​​​​​​编写作业代码 四、​​​​​​​​​​​​​​进行更多配置 五、​​​​​​​​​​​​​​进行深度检查 六、​​​​​​​​​​​​​​进…

AWS SES服务 Golang接入教程(排坑版)

因为刚来看的时候 也迷迷糊糊的 所以 先讲概念 再上代码 一 基础设置 这里需要完成两个最基础的设置任务 1 是验证至少一个收件电子邮箱 2 【很关键】是验证发送域。即身份里的域类型的身份。&#xff08;可以理解为配置你的域名邮箱服务器&#xff08;SMPT&#xff09;为亚马…

PMP–一、二、三模、冲刺、必刷–分类–14.敏捷–技巧--累积流图

文章目录 技巧一模二模三模14.敏捷–敏捷团队的衡量结果–累积流图&#xff1a;1、 敏捷项目的项目经理担心团队在最近的迭代中失去了动力。项目经理应该使用哪两种工具来分析团队绩效&#xff1f;&#xff08;选择两个&#xff09; 冲刺必刷7.成本管理--挣值分析燃尽图仅能了解…

Trm理论 3(ELMo)

LSTM模型 如图&#xff0c;LSTM模型是rnn模型的改良版&#xff0c;通过ft来选择性的保留上一次得到的信息 ELMo模型&#xff08;双向LSTM&#xff09; ELMo模型是对word2vec的改良&#xff0c;改良了word2vec的二义性 对比上下两图&#xff0c;可以发现&#xff0c;WE对预测…

基于约束大于规范的想法,封装缓存组件

架构&#xff1f;何谓架构&#xff1f;好像并没有一个准确的概念。以前我觉得架构就是搭出一套完美的框架&#xff0c;可以让其他开发人员减少不必要的代码开发量&#xff1b;可以完美地实现高内聚低耦合的准则;可以尽可能地实现用最少的硬件资源&#xff0c;实现最高的程序效率…

Linux文件【系统调用接口及进程中对打开文件的管理操作】详细讲解

目录 一、open函数 1.介绍 2.open函数返回值 二、重定向 1.文件描述符的分配规则 2.重定向的本质 3.dup2系统调用 三、C语言库函数中的缓冲区及不同刷新模式 前言&#xff1a; 我们先来简单回顾一下C语言中的文件相关知识 ● 打开文件的方式 r …

数图亮相第三届中国区域零售创新峰会:共绘零售新蓝图,携手迈向新征程

8月31日&#xff0c;备受瞩目的第三届中国区域零售创新峰会在历史悠久的湖北襄阳圆满落下帷幕。在这场零售行业的盛会上&#xff0c;数图信息科技作为重要参会企业&#xff0c;积极参与其中&#xff0c;与众多行业精英共聚一堂&#xff0c;共同擘画零售业的宏伟蓝图。以下是本次…

C程序设计——指针杂谈0

变量和常量讲的差不多了&#xff0c;这里先把指针再深入理解一下&#xff0c;如果你是C语言初学者&#xff0c;本节可能看不太懂&#xff0c;没关系可以以后再看。 变量 当定义变量的时候&#xff0c;本质是在内存中分配了一段空间&#xff0c;这段空间的大小与变量的类型相关…