opencv实战项目二十三:基于BEBLID描述符的特征点匹配实现表盘校正
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
- 前言
- 一、特征点匹配介绍
- 二、特征点检测
- 三、特征描述符计算
- 四,描述符的匹配筛选
- 五,根据匹配结果映射图片
- 六,整体代码:
- 七,效果:
前言
在数字化时代,图像处理技术的应用日益广泛,其中表盘校正作为一项重要技术,在工业自动化、智能监控、时间同步等领域发挥着至关重要的作用。传统的表盘校正方法往往依赖于人工操作,不仅效率低下,而且精度难以保证。随着计算机视觉技术的飞速发展,基于算法的自动表盘校正技术逐渐成为研究热点。
本文将为您介绍一种基于BEBLID(Binary Efficient Boosted Local Identity Features)特征点匹配技术的表盘校正方法。BEBLID作为一种高效的特征描述符,以其独特的优势在众多特征点匹配算法中脱颖而出。本文将从原理、实现步骤以及实际应用等方面,详细阐述如何利用特征点匹配实现表盘的自动校正。
一、特征点匹配介绍
特征点匹配是计算机视觉中的一项核心技术,它能够帮助计算机识别和理解图像中的关键特征,进而实现图像间的对齐、拼接、物体识别等功能。特征点匹配的实现步骤主要包括以下几个方面:
-
特征点检测:首先,在图像中检测出具有显著特征的点。这些特征点可以是角点、边缘点或其他具有独特性质的点。常用的特征点检测算法有SIFT、SURF、ORB等。
-
特征描述符计算:对每个检测到的特征点,计算一个描述符,这个描述符是对特征点周围图像区域的一个定量描述。描述符应具有对图像变换(如缩放、旋转、光照变化等)的不变性。常见的描述符算法有SIFT描述符、SURF描述符、ORB描述符等。
-
特征点匹配:使用特征描述符,通过匹配算法在两幅图像之间找到对应的特征点对。匹配算法通常基于描述符之间的距离,距离越小,匹配度越高。常用的匹配算法有暴力匹配、FLANN等。
-
匹配筛选:由于匹配过程中可能会产生错误的匹配,因此需要筛选出可靠的匹配点。常用的方法包括最近邻距离比测试(NNDR)和RANSAC(随机抽样一致)算法。
-
变换模型估计:利用筛选后的匹配点对,估计一个变换模型(如仿射变换、透视变换等),这个模型描述了两幅图像之间的几何关系。
-
变换应用:将估计的变换模型应用到一幅图像上,以校正图像或实现图像间的对齐。
特征点匹配在计算机视觉领域具有广泛的应用,如图像拼接、三维重建、物体识别等。通过特征点匹配,计算机可以更好地理解图像内容,实现图像的自动处理和分析。
二、特征点检测
特征点检测是计算机视觉中的一个关键步骤,它涉及到在图像中识别出具有独特性质的点,这些点在图像的后续处理中起着至关重要的作用。特征点通常具有以下特点:
- 角点:这些点是图像中物体的边缘的交叉点,它们在图像中具有显著的梯度变化
- 边缘点:这些点位于物体的边缘上,它们的梯度值在某个方向上有一个显著的峰值。
- 中心点:这些点位于物体的中心,它们的梯度值在各个方向上都比较均匀。
- 局部极值点:这些点在局部区域内具有最高的梯度值。
常见的特征点检测的算法有常用的特征点检测算法有SIFT(尺度不变特征变换)、SURF(加速稳健特征)、ORB(Oriented FAST and Rotated BRIEF)等。本次使用的是ORB特征点检测法,
ORB(Oriented FAST and Rotated BRIEF)是一种特征点检测和描述符计算的算法,它是由David G. Lowe和Bruno Lepeletier在2011年提出的。ORB算法结合了FAST(Features from Accelerated Segment Test)和BRIEF(Binary Robust Independent Elementary Features)算法,旨在提供一种快速且稳健的特征检测和描述方法。ORB算法首先使用FAST角点检测器在图像中检测角点。FAST角点检测器通过检测图像中局部区域的边缘变化来确定角点。对于每个检测到的角点,ORB算法计算其方向,并将该方向信息存储在关键点描述中。ORB算法的主要优点是它的高计算效率和稳健性。由于它使用了二进制描述符,因此计算速度非常快。同时,由于BRIEF描述符对光照变化、旋转和尺度变化具有一定的不变性,ORB算法在实际应用中表现出了较好的稳健性。
在opencv中提供了其api为cv2.ORB_create(nfeatures=None, scaleFactor=1.2, nlevels=8, edgeThreshold=31, firstLevel=0, WTA_K=2, scoreType=cv2.ORB_FAST_SCORE, patchSize=31)
,函数介绍:
nfeatures:可选参数,用于指定要检测的最大特征点数量。如果设置为 None,则检测所有检测到的特征点。
scaleFactor:图像金字塔的缩放因子,用于在不同尺度下检测特征点。
nlevels:图像金字塔的层数。
edgeThreshold:用于FAST角点检测的边缘阈值。
firstLevel:图像金字塔的起始层数。
WTA_K:在描述符计算过程中,用于选择K个最佳描述符的参数。
scoreType:描述符的评分类型。
patchSize:用于描述符计算的局部区域大小。
本次只使用orb计算特征点,不计算描述符,故只设置nfeatures特征,并调用类中detect方法检测特征点,使用如下:
detector = cv2.ORB_create(10000)
kpts1 = detector.detect(img1, None)
三、特征描述符计算
描述符是图像特征点的量化表示,它通过对特征点周围图像区域的特征进行编码,从而能够在不依赖于原始图像数据的情况下识别和匹配特征点。描述符的主要目的是提供一种紧凑且信息丰富的表示,以便在图像匹配和识别任务中使用。
描述符的特点包括:
- 紧凑性:描述符通常是一个固定长度的向量,即使对于高分辨率的图像,其大小也非常小。
- 信息丰富:描述符应该能够提供足够的局部图像信息,以便在不同的图像和不同的视角下识别相同的特征点。
- 不变性:描述符应该对图像的某些变换(如缩放、旋转、光照变化等)保持不变,以便在不同的图像条件下仍然能够准确匹配。
本次使用的描述符为BEBLID描述符,BEBLID描述符基于二进制编码,通过对特征点周围的小区域进行采样,并比较该区域的像素值,来生成一个二进制特征向量。与传统的浮点数描述符相比,BEBLID描述符的计算速度更快,因为它只需要比较像素值是否大于某个阈值,而不是计算像素值的差异。
BEBLID描述符的计算过程包括以下几个步骤:
- 选择特征点周围的局部区域:首先,选择特征点周围的一个小区域作为描述符的计算区域。
- 对局部区域内的像素进行采样:在这个区域内,对像素值进行采样,以生成描述符的样本。
- 对采样到的像素值进行比较:比较相邻像素值的大小,如果一个像素值大于另一个像素值,则标记为1,否则标记为0。
- 生成二进制特征向量:将比较结果组合起来,形成一个二进制特征向量。
- 对特征点进行旋转,重复上述步骤:为了提高描述符的稳健性,可以对特征点进行旋转,并重复上述步骤,以获得多个方向上的描述符。
- 组合描述符:将这些描述符组合起来,形成最终的BEBLID描述符。 优点
BEBLID描述符的主要优点包括:
- 高效计算:由于其二进制编码,BEBLID描述符的计算速度非常快,非常适合实时应用。
- 不变性:BEBLID描述符对图像的某些变换(如缩放、旋转、光照变化等)具有较好的不变性,这使得它能够在不同的图像条件下进行有效的匹配。
BEBLID描述符在opencv的api为:descriptor = cv2.xfeatures2d.BEBLID_create(weight=None)
weight:可选参数,用于指定权重因子。权重因子用于在计算描述符时对图像梯度方向直方图进行加权。如果设置为 None,则使用默认权重。
使用:
descriptor = cv2.xfeatures2d.BEBLID_create(0.75)
kpts1, desc1 = descriptor.compute(img1, kpts1)
四,描述符的匹配筛选
在获得描述符之后,需要对描述符进行匹配和筛选,本次使用的方法为knn匹配,并对匹配后的结果的欧氏距离进行筛选,使用代码:
matcher = cv2.DescriptorMatcher_create(cv2.DescriptorMatcher_BRUTEFORCE_HAMMING)
nn_matches = matcher.knnMatch(desc1, desc2, 2)
matched1 = []
matched2 = []
nn_match_ratio = 2 # Nearest neighbor matching ratio
good_matches = []
for m, n in nn_matches:if m.distance < 0.9 * n.distance:good_matches.append(m)
cv2.DescriptorMatcher_create(cv2.DescriptorMatcher_BRUTEFORCE_HAMMING) 是用于创建一个描述符匹配器的函数。这个匹配器是基于Hamming距离的暴力匹配器(Brute-Force Matcher),它用于在两组描述符之间找到匹配对。其中cv2.DescriptorMatcher_BRUTEFORCE_HAMMING:这是一个枚举值,用于指定匹配器使用Hamming距离来计算描述符之间的相似度。Hamming距离是衡量两个等长字符串差异的指标,对于二进制描述符来说,它计算的是两个描述符中不同位的数量。cv2.DescriptorMatcher_create 函数返回一个描述符匹配器对象,这个对象可以用于在两组描述符之间执行匹配操作。通过这个对象,可以调用其方法来执行匹配,如knnMatch、bruteForceMatch等,本次选择的匹配方法为knnmatch。
五,根据匹配结果映射图片
在获取到特征点之后,使用特征点匹配来估计两幅图像之间的仿射变换矩阵,并应用该变换矩阵到输入图像上,以实现图像的校正。
首先提取匹配的特征点对:
dst_pts = np.float32([kpts1[m.queryIdx].pt for m in good_matches]).reshape(-1, 1, 2)
src_pts = np.float32([kpts2[m.trainIdx].pt for m in good_matches]).reshape(-1, 1, 2)
这两行代码从两组匹配的特征点中分别提取出匹配的特征点对。good_matches 是一个包含匹配对的列表,每个匹配对是一个DMatch对象,包含源图像(img1)中的特征点索引(m.queryIdx)和目标图像(img2)中的特征点索引(m.trainIdx)。
然后使用cv2.estimateAffine2D函数估计两幅图像之间的仿射变换矩阵M。src_pts和dst_pts分别是源图像和目标图像中匹配的特征点对。method=cv2.RANSAC参数表示使用RANSAC(随机抽样一致)算法来估计变换矩阵,这是一种鲁棒的方法,可以处理噪声数据。mask是一个布尔数组,表示哪些匹配点对被用于估计变换矩阵。
M, mask = cv2.estimateAffine2D(src_pts, dst_pts, method=cv2.RANSAC)
最后将仿射变换矩阵应用于图像上:
img2_aligned = cv2.warpAffine(img2, M, (width, height))
六,整体代码:
from __future__ import print_function
import cv2
import numpy as np
import argparseparser = argparse.ArgumentParser(description='Code for feature matching and transforming image 2 to image 1.')
parser.add_argument('--input1', help='Path to input image 1.', default=r'F:\cv_traditional\1.png')
parser.add_argument('--input2', help='Path to input image 2.', default=r'F:\cv_traditional\2.png')args = parser.parse_args()img1 = cv2.imread(args.input1)
img2 = cv2.imread(args.input2)if img1 is None or img2 is None:print('Could not open or find the images!')exit(0)detector = cv2.ORB_create(10000)
descriptor = cv2.xfeatures2d.BEBLID_create(0.75)
kpts1 = detector.detect(img1, None)
kpts2 = detector.detect(img2, None)kpts1, desc1 = descriptor.compute(img1, kpts1)
kpts2, desc2 = descriptor.compute(img2, kpts2)matcher = cv2.DescriptorMatcher_create(cv2.DescriptorMatcher_BRUTEFORCE_HAMMING)
nn_matches = matcher.knnMatch(desc1, desc2, 2)matched1 = []
matched2 = []
nn_match_ratio = 2 # Nearest neighbor matching ratio
good_matches = []
for m, n in nn_matches:if m.distance < 0.9 * n.distance:good_matches.append(m)# 提取匹配点对的坐标
dst_pts = np.float32([kpts1[m.queryIdx].pt for m in good_matches]).reshape(-1, 1, 2)
src_pts = np.float32([kpts2[m.trainIdx].pt for m in good_matches]).reshape(-1, 1, 2)# 估计仿射变换矩阵
M, mask = cv2.estimateAffine2D(src_pts, dst_pts, method=cv2.RANSAC)# 应用仿射变换到img2上
height, width = img1.shape[:2]
img2_aligned = cv2.warpAffine(img2, M, (width, height))# 将变换后的img2与img1进行叠加(此处简单叠加,可根据需要调整)
result = cv2.addWeighted(img1, 0.5, img2_aligned, 0.5, 0)
cv2.imshow('img1', img1)
cv2.imshow('img2', img2)
# 显示结果
cv2.imshow('Aligned Image', img2_aligned)
cv2.waitKey(0)
cv2.destroyAllWindows()
七,效果:
目标图像:

输入图像:

校正图像:

相关文章:
opencv实战项目二十三:基于BEBLID描述符的特征点匹配实现表盘校正
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、特征点匹配介绍二、特征点检测三、特征描述符计算四,描述符的匹配筛选五,根据匹配结果映射图片六,整体代码:…...
数据库是全表扫描是怎么扫描法?
全表扫描是数据库服务器用来搜寻表的每一条记录的过程,直到所有符合给定条件的记录返回为止。 在执行全表扫描时,数据库会逐行扫描表中的所有记录,以找到符合查询条件的记录。这种扫描方式适用于没有为查询条件中的字段建立索引的情况。全…...
认准这10款人力资源系统,90%的企业都在用!
本文将为大家推荐十款主流的人力资源系统,为企业选型提供参考! 想象一下,企业在不断发展壮大的过程中,员工数量逐渐增多,人事管理变得越来越复杂。如果没有一个高效的人力资源系统,就如同在大海中航行却没有…...
2024年我的利基出版转型——新战略与重点解析
这篇文章酝酿已久。这是我在网络出版策略上投入数百小时后得出的成果。 像我们这个行业的许多人一样,即网络出版行业,我一直忙于彻底改造整个出版业务。 这是一段漫长的旅程,这是肯定的。 我预感在此过程中还会有更多调整,但我…...
【数据结构】双向链表专题
目录 1.双向链表的结构 2.双向链表的实现 2.1初始化 以参数的形式初始化链表: 以返回值的形式初始化链表: 2.2尾插 2.3打印 2.4头插 2.5尾删 2.6头删 2.7查找 2.8在指定位置之后插入数据编辑 2.9删除pos节点 2.10销毁 3.整理代码 3.1…...
大二上学期计划安排
大二上学期计划安排 学期目标: 加强算法学习,提升算法思维,为以后的算法竞赛做准备学习java知识,学习框架,构建知识体系,深入底层,增强理解增加项目经验,独立完成至少一个项目,并进行交流,优化增强团队凝聚力,营造良好的团队氛围阅读书籍,阅读至少3本以上经典书籍 日常学习安…...
HarmonyOS开发实战( Beta5.0)图片编辑实现马赛克效果详解
鸿蒙HarmonyOS开发往期必看: HarmonyOS NEXT应用开发性能实践总结 最新版!“非常详细的” 鸿蒙HarmonyOS Next应用开发学习路线!(从零基础入门到精通) 介绍 本示例将原图手指划过的区域分割成若干个大小一致的小方格…...
【新书介绍】《JavaScript前端开发与实例教程(微课视频版)(第2版)》
本书重点 无任何基础的初学者,高校JavaScript课程教材。 配套非常全,提供案例源代码、PPT课件、课后习题答案、微课视频、教案、教学大纲、课程实训、期末考试试卷、章节测试、实验报告、学习通建课资源包。 内容简介 JavaScript是开发Web前端必须掌…...
什么是GWAS全基因组关联分析?
什么是全基因组关联分析?(Genome-Wide Association Study,GWAS) 全基因组关联分析(GWAS)是一种在全基因组范围内搜索遗传变异(通常是单核苷酸多态性,SNP)与复杂性状之间关…...
k8s dashboard token 生成/获取
创建示例用户 在本指南中,我们将了解如何使用 Kubernetes 的服务帐户机制创建新用户、授予该用户管理员权限并使用与该用户绑定的承载令牌登录仪表板。 对于以下每个和的代码片段ServiceAccount,ClusterRoleBinding您都应该将它们复制到新的清单文件(如)…...
windows@openssh免密登陆配置@基于powershell快速配置脚本
文章目录 abstract免密自动登录配置介绍👺修改Server配置文件一键脚本修改👺 向ssh server端上传或创建支持免密登录的公钥文件预执行命令👺方式1方式2重启服务以生效👺 傻瓜式配置免密自动登录👺👺准备 操…...
【深度学习】【图像分类】【OnnxRuntime】【Python】VggNet模型部署
【深度学习】【图像分类】【OnnxRuntime】【Python】VggNet模型部署 提示:博主取舍了很多大佬的博文并亲测有效,分享笔记邀大家共同学习讨论 文章目录 【深度学习】【图像分类】【OnnxRuntime】【Python】VggNet模型部署前言Windows平台搭建依赖环境模型转换--pytorch转onnxONN…...
手写排班日历
手写排班日历: 效果图: vue代码如下: <template><div class"YSPB"><div class"title">排班日历</div><div class"banner"><span classiconfont icon-youjiantou click&qu…...
SpringBoot多数据源配置
1、添加依赖 <!-- 数据库驱动 --><!--mysql--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>${mysql-connector-java.version}</version><scope>runtime</sco…...
影响画布微信小程序canvas及skyline和webview用户界面布局的关键流程
影响微信小程序画布canvas及skyline和webview用户界面布局的关键流程 目录 影响微信小程序画布canvas及skyline和webview用户界面布局的关键流程 一、微信小程序canvas开发流程 1.1、官方指南 1.2、客制化开发 第一步:在 WXML 中添加 canvas 组件 第二步&…...
MATLAB图像处理
MATLAB图像处理 MATLAB,作为美国MathWorks公司出品的商业数学软件,以其强大的矩阵运算能力和丰富的函数库,在图像处理领域得到了广泛的应用。MATLAB不仅提供了基础的图像处理功能,还通过图像处理工具箱(Image Process…...
【编程底层思考】性能监控和优化:JVM参数调优,诊断工具的使用等。JVM 调优和线上问题排查实战经验总结
JVM性能监控和优化是确保Java应用程序高效运行的关键环节。以下是一些JVM性能监控和优化的方法,以及使用诊断工具和实战经验的总结: 一、JVM参数调优: 堆大小设置 : - Xms:设置JVM启动时的初始堆大小。 - -Xmx:设置J…...
数据库的实施过程分析
在完成了数据库的逻辑结构设计和物理结构设计后,下一步就是将设计成果转化为现实,这一步骤被称为数据库的实施。数据库实施是数据库开发过程中至关重要的一环,它标志着从设计阶段向实际应用的过渡。本文将为你详细讲解数据库实施的各个关键步…...
【Kubernetes】常见面试题汇总(十二)
目录 36.简述 Kubernetes 的负载均衡器? 37.简述 Kubernetes 各模块如何与 APl Server 通信? 38.简述 Kubernetes Scheduler 作用及实现原理? 36.简述 Kubernetes 的负载均衡器? (1)负载均衡器是暴露服务…...
基于SpringBoot+Vue+MySQL的美术馆管理系统
系统展示 用户前台界面 管理员后台界面 系统背景 随着文化艺术产业的蓬勃发展,美术馆作为展示与传播艺术的重要场所,其管理工作变得日益复杂。为了提升美术馆的运营效率、优化参观体验并加强艺术品管理,我们开发了基于SpringBootVueMySQL的美…...
【Java学习笔记】Arrays类
Arrays 类 1. 导入包:import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序(自然排序和定制排序)Arrays.binarySearch()通过二分搜索法进行查找(前提:数组是…...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...
2024年赣州旅游投资集团社会招聘笔试真
2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...
定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...
基于当前项目通过npm包形式暴露公共组件
1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹,并新增内容 3.创建package文件夹...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)
宇树机器人多姿态起立控制强化学习框架论文解析 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一) 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
如何在网页里填写 PDF 表格?
有时候,你可能希望用户能在你的网站上填写 PDF 表单。然而,这件事并不简单,因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件,但原生并不支持编辑或填写它们。更糟的是,如果你想收集表单数据ÿ…...
Java 二维码
Java 二维码 **技术:**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...
基于 TAPD 进行项目管理
起因 自己写了个小工具,仓库用的Github。之前在用markdown进行需求管理,现在随着功能的增加,感觉有点难以管理了,所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD,需要提供一个企业名新建一个项目&#…...
