python+OpenCV笔记(三十五):特征匹配——基于FLANN的匹配、基于FLANN进行单应性匹配

这篇具有很好参考价值的文章主要介绍了python+OpenCV笔记(三十五):特征匹配——基于FLANN的匹配、基于FLANN进行单应性匹配。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一、基于FLANN的匹配

FLANN匹配流程:

代码编写

二、基于FLANN进行单应性匹配

什么是单应性?

FLANN进行单应性匹配流程

代码编写


         FLANN库全称是Fast Library for Approximate Nearest Neighbors,它是目前最完整的(近似)最近邻开源库。不但实现了一系列查找算法,还包含了一种自动选取最快算法的机制,FLANN使用C++写成,它能够很容易地通过C,MTALAB和Python等绑定提供的库,用在很多环境中。

一、基于FLANN的匹配

FLANN匹配流程:

  1. 导入NumPy, OpenCV, Matplotlib,从文件加载图像(imread)
  2. 使用cv2.SIFT类来检测必要的关键点,并提取特征:
    sift = cv2.SIFT_create()
    kp1, des1 = sift.detectAndCompute(img1, None)
    kp2, des2 = sift.detectAndCompute(img2, None)  
  3. 之前,我们将描述符送入了BFMatcher,用于蛮力匹配。这次,我们将使用cv2.FlannBasedMatcher
    index_params = dict(algorithm=1, tree=5)
    search_params = dict(checks=50)
    flann = cv2.FlannBasedMatcher(index_params, search_params)
    matches = flann.knnMatch(des1, des2, k=2)

    FLANN匹配器接收两个参数:indexindexParams对象和searchParams对象,这些参数以Python中字典(和C++中结构体)的形式传递。
    我们使用了5棵树的核密度树索引算法,FLANN可以并行处理此算法。
    我们对每棵树执行50次检查或者遍历,检查次数越多,可以提供的精度也越高,但是,计算成本也就更高。

  4. 之后,我们应用乘数为0.7的劳氏比率检验。同时,组建一个名为mask_matches 的列表,其中每个元素都是长度为 k(与传给KnnMatch的 k 是一样的) 的子列表,如果匹配成功,则将子列表对应的元素设为1,否则设置为0.

    例如,如果mask_matches=[[0,0],[1,0]],这意味着有两个匹配的关键点:对于第一个关键点,最优和次优匹配都是糟糕的,对于第二个关键点,最佳匹配是好的,次优匹配是糟糕的。注意,我们假设了所有次优匹配都是糟糕的:

    # 准备一个空的掩膜来绘制好的匹配
    mask_matches = [[0, 0] for i in range(len(matches))]
    
    # 向掩膜中添加数据
    for i, (m, n) in enumerate(matches):
        if m.distance < 0.7 * n.distance:
            mask_matches[i] = [1, 0]
  5. 绘制并显示良好匹配,把mask_matches 列表传递给cv2.drawMatchesKnn 作为可选参数,cv2.drawMatchesKnn 只绘制掩膜中标记为好的匹配(值为1)

    img_matches = cv2.drawMatchesKnn(img1, kp1, img2, kp2, matches, None,
                                     matchColor=(0, 255, 0), singlePointColor=(255, 0, 0),
                                     matchesMask=mask_matches, flags=0)

代码编写

import numpy as np
import cv2
from matplotlib import pyplot as plt

# 读入图像
imgname1 = 'E:/qi.png'
imgname2 = 'E:/qiqiqi.png'
img1 = cv2.imread(imgname1)
gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)  # 灰度处理图像
img2 = cv2.imread(imgname2)
gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)  # 灰度处理图像

sift = cv2.SIFT_create()
kp1, des1 = sift.detectAndCompute(img1, None)
kp2, des2 = sift.detectAndCompute(img2, None)

index_params = dict(algorithm=1, tree=5)
search_params = dict(checks=50)
flann = cv2.FlannBasedMatcher(index_params, search_params)
matches = flann.knnMatch(des1, des2, k=2)

# 准备一个空的掩膜来绘制好的匹配
mask_matches = [[0, 0] for i in range(len(matches))]

# 向掩膜中添加数据
for i, (m, n) in enumerate(matches):
    if m.distance < 0.7 * n.distance:
        mask_matches[i] = [1, 0]

img_matches = cv2.drawMatchesKnn(img1, kp1, img2, kp2, matches, None,
                                 matchColor=(0, 255, 0), singlePointColor=(255, 0, 0),
                                 matchesMask=mask_matches, flags=0)

cv2.imshow("FLANN", img_matches)
cv2.waitKey(0)
cv2.destroyAllWindows()

python+OpenCV笔记(三十五):特征匹配——基于FLANN的匹配、基于FLANN进行单应性匹配 可以看到,效果比较理想,几乎所有的匹配项都处于正确的位置。接下来,我们将把这种类型的结果简化为更简洁的几何表示——单应性,他将描述整个匹配对象的姿态,而不是一堆不连续的点。

二、基于FLANN进行单应性匹配

什么是单应性?

        平面的单应性被定义为从一个平面到另一个平面的投影映射。

        书中的作者(见参考)给出这样的解释:单应性是当一张图是另一张图的一个透视畸变时,在两张图中寻找彼此的一种情况。

FLANN进行单应性匹配流程

  1. 导入库,读取灰度格式的图像,检测特征并计算SIFT描述符
  2. 组建一个通过了劳氏比率检验的匹配列表
    good_matches = []
    for m, n in matches:
        if m.distance < 0.7 * n.distance:
            good_matches.append(m)
  3. 从技术上讲,我们最少可以用4个匹配项来计算单应性。但是,如果这4个匹配项中的任意一个有缺陷,都将会破坏结果的准确性。实际中最少用到10个匹配项。对于额外的匹配项,单应性查找算法可以丢弃一些异常值,以便产生与大部分匹配项子集紧密匹配的结果。因此,我们继续检查是否至少有10个好的匹配项:
    MIN_NUM_GOOD_MATCHES = 10
    if len(good_matches) >= MIN_NUM_GOOD_MATCHES:
  4. 如果满足这个条件,那么就查找匹配的关键点的二维坐标,并把这些坐标放入浮点坐标对的两个列表中。一个列表包含查询图像中的关键点坐标,另一个列表包含场景中匹配的关键点坐标:
        src_pts = np.float32(
            [kp1[m.queryIdx].pt for m in good_matches]).reshape(-1, 1, 2)
        dst_pts = np.float32(
            [kp2[m.trainIdx].pt for m in good_matches]).reshape(-1, 1, 2)
  5. 寻找单应性:

        M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)
        mask_matches = mask.ravel().tolist()

    cv2.findHomography参数:

    cv2.findHomography(srcPoints, dstPoints, method, ransacReprojThreshold, mask, maxIters, confidence)

    · srcPoints:源平面中点的坐标矩阵
    · dstPoints:目标平面中点的坐标矩阵
    · method:计算单应矩阵所使用的方法。不同的方法对应不同的参数,具体如下:
                    ·  0: 利用所有点的常规方法
                    ·  RANSAC:基于RANSAC的鲁棒算法
                    `  LMEDS:最小中值鲁棒算法
                    ·  RHO:基于PROSAC的鲁棒算法
    · ransacReprojThreshold:将点对视为内点的最大允许重投影错误阈值(仅用于RANSAC和RHO方法)
    · mask:可选输出掩码矩阵,通常由鲁棒算法(RANSAC或LMEDS)设置。 请注意,输入掩码矩阵是不需要设置的
    · maxIters:RANSAC算法的最大迭代次数,默认值为2000
    · confidence:可信度值,取值范围为0到1

  6. 执行透射转换,取查询图像的矩形角点,并将其投影到场景中,从而画出边界

        h, w = img1.shape[:2]
        src_corners = np.float32(
            [[0, 0], [0, h - 1], [w - 1, h - 1], [w - 1, 0]]).reshape(-1, 1, 2)
        dst_corners = cv2.perspectiveTransform(src_corners, M)
        img2 = cv2.polylines(img2, [np.int32(dst_corners)], True, (255, 0, 0), 3, cv2.LINE_AA)
  7. 然后,继续绘制关键点并显示可视化效果

代码编写

import numpy as np
import cv2
from matplotlib import pyplot as plt

# 读入图像
imgname1 = 'E:/qiqiqi.png'
imgname2 = 'E:/train1.jpg'
img1 = cv2.imread(imgname1)
gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)  # 灰度处理图像
img2 = cv2.imread(imgname2)
gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)  # 灰度处理图像

sift = cv2.SIFT_create()
kp1, des1 = sift.detectAndCompute(img1, None)
kp2, des2 = sift.detectAndCompute(img2, None)

index_params = dict(algorithm=1, tree=5)
search_params = dict(checks=50)
flann = cv2.FlannBasedMatcher(index_params, search_params)
matches = flann.knnMatch(des1, des2, k=2)

good_matches = []
for m, n in matches:
    if m.distance < 0.7 * n.distance:
        good_matches.append(m)

MIN_NUM_GOOD_MATCHES = 10
if len(good_matches) >= MIN_NUM_GOOD_MATCHES:
    src_pts = np.float32(
        [kp1[m.queryIdx].pt for m in good_matches]).reshape(-1, 1, 2)
    dst_pts = np.float32(
        [kp2[m.trainIdx].pt for m in good_matches]).reshape(-1, 1, 2)
    M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)
    mask_matches = mask.ravel().tolist()

    h, w = img1.shape[:2]
    src_corners = np.float32(
        [[0, 0], [0, h - 1], [w - 1, h - 1], [w - 1, 0]]).reshape(-1, 1, 2)
    dst_corners = cv2.perspectiveTransform(src_corners, M)
    img2 = cv2.polylines(img2, [np.int32(dst_corners)], True, (255, 0, 0), 3, cv2.LINE_AA)

else:
    mask_matches = None

draw_params = dict(matchColor=(0, 255, 0), singlePointColor=None, matchesMask=mask_matches, flags=2)

img3 = cv2.drawMatches(img1, kp1, img2, kp2, good_matches, None, **draw_params)

cv2.imshow("FLANN", img3)
cv2.waitKey(0)
cv2.destroyAllWindows()

python+OpenCV笔记(三十五):特征匹配——基于FLANN的匹配、基于FLANN进行单应性匹配

python+OpenCV笔记(三十五):特征匹配——基于FLANN的匹配、基于FLANN进行单应性匹配


【参考】:OpenCV 4计算机视觉 Python语言实现(原书第三版) 作者:Joseph Howse文章来源地址https://www.toymoban.com/news/detail-454411.html

到了这里,关于python+OpenCV笔记(三十五):特征匹配——基于FLANN的匹配、基于FLANN进行单应性匹配的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • OpenCV Python – 使用SIFT算法实现两张图片的特征匹配

    1.要实现在大图中找到任意旋转、缩放等情况下的小图位置,可以使用特征匹配算法,如 SIFT (尺度不变特征变换) 或 SURF (加速稳健特征)。这些算法可以在不同尺度和旋转情况下寻找匹配的特征点 2.我们使用了 SIFT 算法检测和匹配特征点,然后使用 RANSAC 算法计算透视变换矩阵

    2024年02月06日
    浏览(49)
  • OpenCV(三十五):凸包检测

    1.凸包检测介绍       凸包检测是计算凸包的一种技术,凸包就是:给定二维平面上的点集,将最外层的点连接起来构成的凸边形,它是包含点集中所有的点。 2.凸包检测函数convexHull() void cv::convexHull ( InputArray  points, OutputArray hull, boolclockwise = false, bool   returnPoints = true ) p

    2024年02月09日
    浏览(40)
  • 特征点的检测与匹配(ORB,SIFT,SURFT比较)[opencv-python]

    本文旨在总结opencv-python上特征点的检测和匹配。 1、特征点的检测(包括:ORB,SIFT,SURFT) 2、特侦点匹配方法 (包括:暴力法,FLANN,以及随机抽样一致性优化RANSAC算法) 注:由于SURF专利问题,所以opencv官方包目前不支持SURF但支持ORB和SIFT,安装opencv-contrib-python包就可以解决 一

    2024年02月06日
    浏览(50)
  • 【OpenCV】第十五章: 模板匹配

    第十五章: 模板匹配 模板匹配就是在给定的图片中查找和模板最相似的区域。 实现的方法是:将模板在图片上滑动(从左向右,从上向下),遍历所有滑窗,计算匹配度,将所有计算结果保存在一个矩阵种,并将矩阵中匹配度最高的值作为匹配结果。 一、单模板匹配 1、匹配函

    2024年02月02日
    浏览(44)
  • OPENCV实现暴力特征匹配

    2024年02月10日
    浏览(38)
  • opencv学习-特征匹配

    opencv特征匹配方法有两种,分别是: BF(Brute-Force),暴力特征匹配方法。它使用第一组中的每个特征的描述子,与第二组中的所有特征描述子进行匹配,计算它们之间的差距,然后将最接近一个匹配返回。 在进行批量特征匹配时,FLANN速度更快。 由于它使用的是邻近近似值

    2024年02月13日
    浏览(38)
  • OpenCV之特征点匹配

            特征点探测方法有goodFeaturesToTrack(),cornerHarris()和SURF()。一般使用goodFeaturesToTrack()就能获得很好的特征点。goodFeaturesToTrack()定义: image:源图像; corners:检测到的特征点位置; maxcorner:为返回的特征点个数设置上限。 qualityLevel:反映出一个角形特征在它之前的强度,设

    2024年02月12日
    浏览(39)
  • OpenCV实战(18)——特征匹配

    在关键点检测一节中,我们学习了如何检测图像中的关键点,其目的是用于执行局部图像分析。这些关键点需要足够独特,以便在具有相同对象的不同图像中能够检测到相同的点。 基于关键点执行图像分析需要构建丰富的表示来唯一地描述这些关键点,本节将重点介绍如何从

    2024年02月03日
    浏览(46)
  • opencv特征匹配算法原理

    算法步骤: FAST进行特征点提取是根据当前点领域内的点的差值作为特征点的筛选标准 ( 1 ) 选择像素 p ,该像素值为 I p ,确定筛选阈值 T ( 2 ) 计算以 p 为圆心 3 为半径的 16 个像素点的灰度值 I x 和圆心 p 的灰度值 I p 的差值,如果存在连续 n 个点(算法第一个版本为 12 ) 满

    2024年02月03日
    浏览(46)
  • 【OpenCV 例程 300篇】251. 特征匹配之暴力匹配

    『youcans 的 OpenCV 例程300篇 - 总目录』 特征匹配是特征检测和特征描述的基本应用,在在图像拼接、目标识别、三维重建等领域的应用非常广泛。 基于特征描述符的特征点匹配是通过对两幅图像的特征点集合内的关键点描述符的相似性比对来实现的。分别对参考图像(Refere

    2024年02月02日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包