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的美…...

【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...

JavaSec-RCE
简介 RCE(Remote Code Execution),可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景:Groovy代码注入 Groovy是一种基于JVM的动态语言,语法简洁,支持闭包、动态类型和Java互操作性,…...

【OSG学习笔记】Day 18: 碰撞检测与物理交互
物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...

376. Wiggle Subsequence
376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...

Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...
稳定币的深度剖析与展望
一、引言 在当今数字化浪潮席卷全球的时代,加密货币作为一种新兴的金融现象,正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而,加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下,稳定…...
NPOI Excel用OLE对象的形式插入文件附件以及插入图片
static void Main(string[] args) {XlsWithObjData();Console.WriteLine("输出完成"); }static void XlsWithObjData() {// 创建工作簿和单元格,只有HSSFWorkbook,XSSFWorkbook不可以HSSFWorkbook workbook new HSSFWorkbook();HSSFSheet sheet (HSSFSheet)workboo…...

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement
Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement 1. LAB环境2. L2公告策略2.1 部署Death Star2.2 访问服务2.3 部署L2公告策略2.4 服务宣告 3. 可视化 ARP 流量3.1 部署新服务3.2 准备可视化3.3 再次请求 4. 自动IPAM4.1 IPAM Pool4.2 …...

VisualXML全新升级 | 新增数据库编辑功能
VisualXML是一个功能强大的网络总线设计工具,专注于简化汽车电子系统中复杂的网络数据设计操作。它支持多种主流总线网络格式的数据编辑(如DBC、LDF、ARXML、HEX等),并能够基于Excel表格的方式生成和转换多种数据库文件。由此&…...