python数字图像处理基础(九)——特征匹配

news2024/9/29 11:38:34

目录

      • 蛮力匹配(ORB匹配)
      • RANSAC算法
      • 全景图像拼接

蛮力匹配(ORB匹配)

Brute-Force匹配非常简单,首先在第一幅图像中选取一个关键点然后依次与第二幅图像的每个关键点进行(描述符)距离测试,最后返回距离最近的关键点.

对于BF匹配器,首先我们必须使用**cv2.BFMatcher()**创建 BFMatcher 对象。它需要两个可选的参数:

  • normType:它指定要使用的距离测量,默认情况下,它是cv2.NORM_L2,它适用于SIFT,SURF等(cv2.NORM_L1也在那里)。对于基于二进制字符串的描述符,如ORB,BRIEF,BRISK等,应使用cv2.NORM_HAMMING,使用汉明距离作为度量,如果ORB使用WTA_K == 3or4,则应使用cv2.NORM_HAMMING2
  • crossCheck:默认值为False。如果设置为True,匹配条件就会更加严格,只有到A中的第i个特征点与B中的第j个特征点距离最近,并且B中的第j个特征点到A中的第i个特征点也是最近时才会返回最佳匹配,即这两个特征点要互相匹配才行

两个重要的方法是BFMatcher.match()BFMatcher.knnMatch(), 第一个返回最佳匹配, 第二种方法返回k个最佳匹配,其中k由用户指定.

使用cv2.drawMatches()来绘制匹配的点,它会将两幅图像先水平排列,然后在最佳匹配的点之间绘制直线。如果前面使用的BFMatcher.knnMatch(),现在可以使用函数cv2.drawMatchsKnn为每个关键点和它的个最佳匹配点绘制匹配线。如果要选择性绘制就要给函数传入一个掩模.

一对一匹配 BFMatcher.match()

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

img1 = cv2.imread('./image/girl1.jpg')
img2 = cv2.imread('./image/girl2.jpg')

sift = cv2.SIFT_create()

# kp代表特征点 des每个点对应特征向量
kp1, des1 = sift.detectAndCompute(img1, None)
kp2, des2 = sift.detectAndCompute(img2, None)

bf = cv2.BFMatcher(crossCheck=True)  # 可选对象crossCheck

# 1对1匹配
matches = bf.match(des1, des2)
matches = sorted(matches, key=lambda x: x.distance)  # 排序,通过距离来度量

img3 = cv2.drawMatches(img1, kp1, img2, kp2, matches[:30], None, flags=2)  # matches[:10] 距离前十的给显示出来,即显示十条匹配线

cv2.imshow('img', img3)
cv2.waitKey(0)
cv2.destroyAllWindows()

k对最佳匹配 BFMatcher.knnMatch()

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

img1 = cv2.imread('./image/girl1.jpg')
img2 = cv2.imread('./image/girl2.jpg')

sift = cv2.SIFT_create()

# kp代表特征点 des每个点对应特征向量
kp1, des1 = sift.detectAndCompute(img1, None)
kp2, des2 = sift.detectAndCompute(img2, None)

# k对最佳匹配
bf = cv2.BFMatcher()
matches = bf.knnMatch(des1, des2, k=2)

good = []
for m, n in matches:
    # 过滤方法
    if m.distance < 0.75 * n.distance:
        good.append([m])

img3 = cv2.drawMatchesKnn(img1, kp1, img2, kp2, good, None, flags=2)

cv2.imshow('img', img3)
cv2.waitKey(0)
cv2.destroyAllWindows()

RANSAC算法

蛮力匹配是一种简单而直观的匹配方法,适用于小规模的特征点匹配。通过比较所有可能的特征点对,找到最佳匹配。而RANSAC算法则通过随机采样和一致性检验,从包含噪声的数据中估计出正确的模型参数,对于一些存在噪声和异常值的情况,RANSAC能够更稳健地估计模型。

利用RANSAC算法计算变换矩阵

RANSAC是"RANdom SAmple Consensus"(随机一致采样)的缩写。该方法是用来找到正确模型来拟合带有噪声数据的迭代方法。给定一个模型,例如点集之间的单应性矩阵。基本的思想是:数据中包含正确的点和噪声点,合理的模型应该能够在描述正确数据点的同时摒弃噪声点。

此外还有ORB匹配、SIFT的特征匹配、基于FLANN的匹配器的匹配,等等

全景图像拼接

全景图像拼接是将多张图像拼接成一张全景图的任务。在这个过程中,特征点匹配和单应性矩阵估计是关键的步骤。你提到的使用SIFT找到特征点,并通过单应性矩阵将图像进行变换,是一种常见的方法。这样可以在不同视角或位置拍摄的图像中找到对应的特征点,从而实现拼接。

通过SIFT找特征点

关于单应性矩阵(H矩阵):

利用两个图像中至少四个特征点能够求解一个单应性矩阵(homography matrix),然后用这个单应性矩阵能够将图像1中的某个坐标变换到图像2中对应的位置。然而,矩阵的推导是来自于相机在不同位姿拍摄同一个三维平面,所以使用opencv计算单应性矩阵的时候前提是两个图像对应区域必须是同一平面。

当进行全景图像拼接时,常常需要使用RANSAC算法估计单应性矩阵。下面是一个简单的示例代码,其中包括特征点匹配、RANSAC算法和全景图像拼接的步骤。

import cv2
import numpy as np

def find_keypoints_and_descriptors(image):
    # 使用SIFT算法找到图像的关键点和描述符
    sift = cv2.SIFT_create()
    kp, des = sift.detectAndCompute(image, None)
    return kp, des

def match_keypoints(des1, des2):
    # 使用BFMatcher进行特征点匹配
    bf = cv2.BFMatcher()
    matches = bf.knnMatch(des1, des2, k=2)
    
    # 使用比值测试排除不好的匹配
    good = []
    for m, n in matches:
        if m.distance < 0.75 * n.distance:
            good.append(m)
    
    return good

def ransac_homography(matches, kp1, kp2, reproj_thresh=4.0):
    # 将匹配的关键点转换为numpy数组
    src_pts = np.float32([kp1[m.queryIdx].pt for m in matches]).reshape(-1, 1, 2)
    dst_pts = np.float32([kp2[m.trainIdx].pt for m in matches]).reshape(-1, 1, 2)
    
    # 使用RANSAC算法估计单应性矩阵
    H, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, reproj_thresh)
    
    return H

def stitch_images(image1, image2, H):
    # 将图像1进行透视变换,将其叠加到图像2上
    rows1, cols1 = image1.shape[:2]
    rows2, cols2 = image2.shape[:2]
    warp_img1 = cv2.warpPerspective(image1, H, (cols1 + cols2, rows2))
    warp_img1[:rows2, :cols2] = image2
    
    return warp_img1

if __name__ == "__main__":
    # 读取两张图像
    img1 = cv2.imread('image1.jpg')
    img2 = cv2.imread('image2.jpg')
    
    # 找到关键点和描述符
    kp1, des1 = find_keypoints_and_descriptors(img1)
    kp2, des2 = find_keypoints_and_descriptors(img2)
    
    # 进行特征点匹配
    matches = match_keypoints(des1, des2)
    
    # 使用RANSAC估计单应性矩阵
    H = ransac_homography(matches, kp1, kp2)
    
    # 进行全景图像拼接
    result = stitch_images(img1, img2, H)
    
    # 显示拼接结果
    cv2.imshow('Panorama', result)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

为了达到更好的拼接效果,可能需要使用更复杂的图像配准和融合技术。


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

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

相关文章

爆推联盟,推广接单平台定制开发(智创有术)

爆推联盟官网、推广接单平台、很多朋友问我做项目要怎么做&#xff0c;项目怎么选&#xff1f;那些项目比较稳定靠谱&#xff0c;赚钱还不错的平台&#xff0c;其实网上的项目很多&#xff0c;别说做&#xff0c;看都看不过来&#xff0c;我们做项目最主要的就是稳定嘛&#xf…

智能化未来:NFC技术助力数字化社区

引言 数字化转型深刻改变着社区管理的方式&#xff0c;其中NFC技术作为一种近场通讯技术&#xff0c;正在为数字社区的智能化未来提供强有力的支持。 NFC技术简介 近场通讯技术(NFC)是一种无线通信技术&#xff0c;能够实现设备之间的近距离通讯。在数字社区建设中&#xf…

第一讲_HarmonyOS应用开发环境准备

HarmonyOS应用开发环境准备 1. 知识储备2. 环境搭建2.1 安装node.js2.2 配置node.js2.3 安装命令行工具2.4 安装DevEco Studio2.5 配置DevEco Studio 1. 知识储备 HarmonyOS提供了一套UI开发框架&#xff0c;即方舟开发框架&#xff08;ArkUI框架&#xff09;。方舟开发框架可…

#开发环境篇:HBuilderX自定义括号颜色激活时list和tab的背景色

Settings.json 配置 位置在 设置------> 源码设置里面 {"beautify.useProjectConfigFile": true,"browsers.config": {"Chrome.path": "C:/Program Files/Google/Chrome/Application/chrome.exe"},"defaultFomat.vue":…

判断SD-WAN是否适用于你的企业的关键问题

企业网络的演进已经将SD-WAN&#xff08;软件定义广域网&#xff09;推到了风口浪尖。不论企业规模如何&#xff0c;它们都在寻求适应不断变化的网络环境的最佳解决方案。尽管SD-WAN的部署带来了多方面的优势&#xff0c;但企业在决定是否采用SD-WAN时需要考虑一些关键问题。 关…

SafeTpack—基于AURIX 2G的功能安全目标解决方案

产品概述 SafeTpack是专门针对于英飞凌AURIX 2G系列芯片的功能安全解决方案&#xff0c;由英飞凌下属子公司Hitex按照ISO26262-10作为独立于环境的安全要素&#xff08;SEOOC&#xff09;研发。根据ISO26262-5中的要求&#xff0c;系统需要根据不同ASIL等级的要求&#xff0c;针…

目标文献分析方法

如何正确选题&#xff1f; 不仅仅是题目&#xff0c;而是研究工作的起步选题步骤&#xff1f; 发现问题选择方向调查研究分析论证确定选题 中国知网 深度学习方向词 1检索&#xff1a;深度学习 医疗影像 1 发表时间要最新 2 显示50个&#xff0c;全选 3 导出文献格式Ref 4 导…

JVM垃圾回收机制及思维导图

一、Java垃圾回收机制 在java中&#xff0c;程序员是不需要显示的去释放一个对象的内存的&#xff0c;而是由虚拟机自行执行。在JVM中&#xff0c;有一个垃圾回收线程&#xff0c;它是低优先级的&#xff0c;在正常情况下是不会执行的&#xff0c;只有在虚拟机空闲或者当前堆内…

官宣!Meta正在训练Llama 3,将继续开源

1月19日&#xff0c;全球社交、科技巨头Meta的联合创始人兼首席执行官-Zuck&#xff08;扎克伯格&#xff09;在is宣布&#xff0c;正在训练Llama 3并且以负责任地方式继续开源。 Zuck表示&#xff0c;预计到2024年底&#xff0c;Meta将拥有350,000块H100&#xff0c;如果算上…

JAVA SECS发送Report C#处理SECS Report SECS发送事件资料大全 S6F11 建立通讯S1F13

发送S6F11非常简单&#xff0c;只需5~6行代码&#xff0c;最核心是代码清晰易懂。 任何人都可以一看就能上手&#xff0c;如果说用代码可读性作为不可替代性的壁垒就无话可说了。 private void buttonS6F11_Click(object sender, EventArgs e) {int nTransaction 0;// 数据部…

Java中创建List接口、ArrayList类和LinkedList类的常用方法(一)

List接口 要了解List接口&#xff0c;就不得不说起Java的集合框架。 &#xff08;该图来自菜鸟教程&#xff09; Collection接口和Map接口 Java 集合框架主要包括两种类型的容器&#xff0c;集合Collection和图Map。 Collection接口代表了单列集合&#xff0c;它包含了一组…

画面滤镜特效SDK,企业级视频处理技术方案

视频处理技术日新月异&#xff0c;对于企业而言&#xff0c;如何快速、高效地处理视频内容&#xff0c;增加其观赏性和吸引力&#xff0c;成为了一项重要的挑战。美摄科技画面滤镜特效SDK&#xff0c;作为一款全面的视频处理工具&#xff0c;为企业提供了一种高效、灵活的视频处…

元宇宙:智慧城市建设的未来引擎与价值之源

在21世纪的技术大潮中&#xff0c;元宇宙的出现无疑是一场革命&#xff0c;其独特的概念与价值已经引发了全球范围内的关注。 作为新兴科技的前沿&#xff0c;元宇宙为智慧城市建设带来了无限的可能性和价值&#xff0c;有望成为未来城市发展的核心动力。 元宇宙&#xff0c;这…

虚拟线程探索与实践(JDK19)

优质博文&#xff1a;IT-BLOG-CN 一、简介 虚拟线程是轻量级线程&#xff0c;极大地减少了编写、维护和观察高吞吐量并发应用的工作量。虚拟线程是由JEP 425提出的预览功能&#xff0c;并在JDK 19中发布&#xff0c;JDK 21中最终确定虚拟线程&#xff0c;以下是根据开发者反馈…

JAVA实现向Word模板中插入Base64图片和数据信息

目录 需求一、准备模板文件二、引入Poi-tl、Apache POI依赖三、创建实体类&#xff08;用于保存向Word中写入的数据&#xff09;四、实现Service接口五、Controller层实现 需求 在服务端提前准备好Word模板文件&#xff0c;并在用户请求接口时服务端动态获取图片。数据等信息插…

【Week-P5】CNN运动鞋品牌识别

文章目录 一、环境配置二、准备数据三、搭建网络结构四、开始训练五、查看训练结果六、总结6.1 torch.optim.lr_scheduler.StepLR 等间隔动态调整6.2 lr_scheduler.LambdaLR 自定义学习率更新函数6.3 lr_scheduler.MultiStepLR 特定epoch中调整学习率6.4 本文四种学习率方法得到…

详细的说说mfc110u.dll丢失的解决方法分享,四种解决办法的详细步骤

在电脑运行过程中&#xff0c;有时会遇到各种各样的错误提示&#xff0c;比如“由于找不到mfc110u.dll&#xff0c;无法继续执行代码”&#xff0c;这不仅令人困扰&#xff0c;也影响了我们的工作和娱乐体验。如果你也在为mfc110u.dll缺失问题感到苦恼&#xff0c;那么你来对地…

Ubuntu重启后进入initramfs导致无法开机

今晚&#xff0c;我的电脑意外关机&#xff0c;重新开机后打开了虚拟机后出现initramfs&#xff0c;一直无法开机。该虚拟机使用的是 vm17,系统是ubuntu20, 解决方案 使用如下命令查看和识别磁盘、分区或文件系统的信息 在initramfs后面输入 fsck /dev/sdb4 ,即修复上面损坏的…

非线性最小二乘问题的数值方法 —— 狗腿法 Powell‘s Dog Leg Method (I - 原理与算法)

Title: 非线性最小二乘问题的数值方法 —— 狗腿法 Powell’s Dog Leg Method (I - 原理与算法) 文章目录 I. 前言II. 线搜索类型和信赖域类型1. 线搜索类型 —— 最速下降法2. 信赖域类型3. 柯西点 III. 狗腿法的原理1. 狗腿法的构建2. 狗腿法的优化说明3. 狗腿法的插值权重 I…

Spring Security 优化鉴权注解:自定义鉴权注解的崭新征程

文章目录 1. 引言2. Spring Security基础2.1 Spring Security概述2.2 PreAuthorize注解 3. 自定义鉴权注解的优势3.1 业务语义更明确3.2 参数化鉴权更灵活3.3 可维护性更好 4. 实现自定义鉴权注解4.1 创建自定义注解4.2 实现鉴权逻辑4.3 注册自定义注解和逻辑4.4 使用自定义注解…