Opencv计算机视觉编程攻略-第九节 描述和匹配兴趣点

       一般而言,如果一个物体在一幅图像中被检测到关键点,那么同一个物体在其他图像中也会检测到同一个关键点。图像匹配是关键点的常用功能之一,它的作用包括关联同一场景的两幅图像、检测图像中事物的发生地点等等。

1.局部模板匹配

        凭单个像素就判断两个关键点的相似度显然是不够的,因此要在匹配过程中考虑每个关键
点周围的图像块,
对图像块中的像素进行逐个比较,但是并不是最可靠的。

      第一步,使用FAST 检测器进行关键点提取:

// 定义特征检测器
cv::Ptr<cv::FeatureDetector> ptrDetector; // 泛型检测器指针
ptrDetector= // 这里选用FAST 检测器
cv::FastFeatureDetector::create(80);
// 检测关键点
ptrDetector->detect(image1,keypoints1);
ptrDetector->detect(image2,keypoints2);

      第二步,定义匹配框,在每个图像对的关键点之间进行匹配,这里使用逐像素相差匹配:

// 在第二幅图像中找出与第一幅图像中的每个关键点最匹配的
cv::Mat result;
std::vector<cv::DMatch> matches;
// 针对图像一的全部关键点
for (int i=0; i<keypoints1.size(); i++) {// 定义图像块neighborhood.x = keypoints1[i].pt.x-nsize/2;neighborhood.y = keypoints1[i].pt.y-nsize/2;// 如果邻域超出图像范围,就继续处理下一个点if (neighborhood.x<0 || neighborhood.y<0 ||neighborhood.x+nsize >= image1.cols ||neighborhood.y+nsize >= image1.rows)continue;// 第一幅图像的块patch1 = image1(neighborhood);// 存放最匹配的值cv::DMatch bestMatch;// 针对第二幅图像的全部关键点for (int j=0; j<keypoints2.size(); j++) {// 定义图像块neighborhood.x = keypoints2[j].pt.x-nsize/2;neighborhood.y = keypoints2[j].pt.y-nsize/2;// 如果邻域超出图像范围,就继续处理下一个点if (neighborhood.x<0 || neighborhood.y<0 ||neighborhood.x + nsize >= image2.cols ||neighborhood.y + nsize >= image2.rows)continue;// 第二幅图像的块patch2 = image2(neighborhood);// 匹配两个图像块cv::matchTemplate(patch1,patch2,result, cv::TM_SQDIFF);// 检查是否为最佳匹配if (result.at<float>(0,0) < bestMatch.distance) {bestMatch.distance= result.at<float>(0,0);bestMatch.queryIdx= i;bestMatch.trainIdx= j;}}// 添加最佳匹配matches.push_back(bestMatch);}

      第三步,选择置信度最高的一些点,进行展示:

// 提取25 个最佳匹配项
std::nth_element(matches.begin(),matches.begin() + 25,matches.end());
matches.erase(matches.begin() + 25,matches.end());// 绘制图像
cv::Mat matchImage;
cv::drawMatches(image1,keypoints1, // 第一幅图像image2,keypoints2, // 第二幅图像matches, // 匹配项的向量cv::Scalar(255,255,255), // 线条颜色cv::Scalar(255,255,255)); // 点的颜色

        上述方法使用图块之间相似度进行评估,也可以使用opencv中的区域模板匹配方法进一步增大搜索精确度:

// 定义搜索区域
cv::Mat roi(image2, // 这里用图像的上半部分
cv::Rect(0,0,image2.cols,image2.rows/2));
// 进行模板匹配
cv::matchTemplate(roi, // 搜索区域
target, // 模板
result, // 结果
cv::TM_SQDIFF); // 相似度
// 找到最相似的位置
double minVal, maxVal;
cv::Point minPt, maxPt;
cv::minMaxLoc(result, &minVal, &maxVal, &minPt, &maxPt);
// 在相似度最高的位置绘制矩形
// 本例中为minPt
cv::rectangle(roi, cv::Rect(minPt.x, minPt.y,
target.cols, target.rows), 255);

2.描述并匹配局部强度值模式

       在图像分析中,可以用邻域包含的视觉信息来标识每个特征点,以便区分各个特征点。特征描述子通常是一个N 维的向量,在光照变化和拍摄角度发生微小扭曲时,它描述特征点的方式不会发生变化, 通常可以用简单的差值矩阵来比较描述子,例如用欧几里得距离等

       基于特征的方法都包含一个检测器和一个描述子组件,与cv::Feature2D 相关的类也一样,它们都有一个检测函数(用于检测兴趣点)和一个计算函数(用于计算兴趣点的描述子)cv::SURF
和cv::SIFT,检测流程和上述一致。

// 1. 定义关键点的容器
std::vector<cv::KeyPoint> keypoints1;
std::vector<cv::KeyPoint> keypoints2;// 2. 定义特征检测器
cv::Ptr<cv::Feature2D> ptrFeature2D =
cv::xfeatures2d::SURF::create(2000.0);// 3. 检测关键点
ptrFeature2D->detect(image1,keypoints1);
ptrFeature2D->detect(image2,keypoints2);// 4. 提取描述子
cv::Mat descriptors1;
cv::Mat descriptors2;
ptrFeature2D->compute(image1,keypoints1,descriptors1);
ptrFeature2D->compute(image2,keypoints2,descriptors2);// 5. 构造匹配器
cv::BFMatcher matcher(cv::NORM_L2);cv::BFMatcher matcher2(cv::NORM_L2, // 度量差距
true); // 可以开启 交叉检查标志// 匹配两幅图像的描述子
std::vector<cv::DMatch> matches;
matcher.match(descriptors1,descriptors2, matches);

      好的特征描述子不受照明和视角微小变动的影响,也不受图像中噪声的影响,因此它们通常
基于局部强度值的差值,SURF 描述子在关键点周围局部地应用下面的简易内核:

        第一个内核度量水平方向的局部强度值差值(标为dx),第二个内核度量垂直方向的差值(标为dy)。通常将用于提取描述子向量的邻域尺寸定为特征值缩放因子的20 倍(即20σ)。然后把这个正方形区域划分成更小的4×4 子区域。对于每个子区域,在5×5 等分的位置上(用尺寸为2σ的内核)计算内核反馈值(dx 和dy)。

     使用SURF 和SIFT 的特征和描述子可以进行尺度无关的匹配,能够取得较好的效果。

3.用二值描述子匹配关键点

        上述描述子是浮点数类型的向量,大小为64、128等,这导致对它们的操作将耗资巨大,为了减少内存使用、降低计算量,人们引入了将一组比特位(0 和1)组合成二值描述子的概念。这里的难点在于,既要易于计算,又要在场景和视角变化时保持鲁棒性。

// 1. 定义特征检测器/描述子
// Construct the ORB feature object
cv::Ptr<cv::Feature2D> feature = cv::ORB::create(60);
// 大约60 个特征点
// 检测并描述关键点
// 2. 检测ORB 特征
feature->detectAndCompute(image1, cv::noArray(),
keypoints1, descriptors1);
feature->detectAndCompute(image2, cv::noArray(),
keypoints2, descriptors2);// 3. 构建匹配器
cv::BFMatcher matcher(cv::NORM_HAMMING); // 二值描述子一律使用Hamming 规范】// 4.匹配两幅图像的描述子
std::vector<cv::DMatch> matches;
matcher.match(descriptors1, descriptors2, matches);

       ORB 算法在多个尺度下检测特征点,这些特征点含有方向。基于这些特征点,ORB 描述子通过简单比较强度值,提取出每个关键点的表征,在BRIEF 描述子的基础上构建的,然后在关键点周围的邻域内随机选取一对像素点,创建一个二值描述子。

       比较这两个像素点的强度值,如果第一个点的强度值较大,就把对应描述子的位(bit)设为1,否则就设为0。对一批随机像素点对进行上述处理,就产生了一个由若干位(bit)组成的描述子,通常采用128 到512 位(成对地测试)。

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

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

相关文章

C++内存管理优化实战:提升应用性能与效率

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家、CSDN平台优质创作者&#xff0c;高级开发工程师&#xff0c;数学专业&#xff0c;拥有高级工程师证书&#xff1b;擅长C/C、C#等开发语言&#xff0c;熟悉Java常用开发技术&#xff0c;能熟练应用常用数据库SQL server,Oracle…

17-产品经理-创建发布

点击“发布”-“创建发布”。 填写发布名称&#xff0c;选择测试的版本。还可以设置此次发布是否为“里程碑”。 点击“保存”后&#xff0c;进入该发布详情页面。需要为此次发布关联需求、已解决BUG、以及遗留BUG。可以通过设置条件&#xff0c;进行“搜索”&#xff0c;然后批…

Axure RP9.0教程 | 内联框架 对应html 元素中的iframe标签 (打开内部页面和外部网址)

文章目录 引言I 打开内部页面II 打开外部网址操作效果引言 应用场景: 选择右侧不同栏目,左侧内容发生变化 I 打开内部页面 在公用元件库中找到内联框架图标,将其拖到画布中,设置其宽、高;在右侧添加三个按钮,分别用来跳转三个不同的页面;在内部框架中,添加三个子页面,…

在1panel中安装WebUI

如果需要建站&#xff0c;那得选安装Openresty。点击应用商店&#xff0c;安装 Openresty 接下来安装Ollama&#xff0c;可以部署本地模型提供给WebUi平台使用 最后是安装 WebUi&#xff0c;安装时需要填写Ollama的地址: 容器地址&#xff1a;30000 这些安装都很方便&#xf…

项目难点亮点

Vue项目 RBAC设计 用户权限设置 WebSocket 消息处理 BPMN扩展 跨语言模型的调用 大片文件(影像,模型等,数据-模型集成) 组件&指令封装 低代码表单构建、BPMN编辑器集成与实现 通用参考点 若依(RuoYi)是一个基于 Vue.js 和 Spring Boot 的前后端分离权限管理系…

JVM生产环境调优实战

案例三&#xff1a;JVM频繁Full GC优化 1. 项目背景&#xff08;Situation&#xff09; 在云中万维跨境支付的反洗钱系统中&#xff0c;我们负责对海量交易数据进行实时规则校验&#xff0c;以确保符合监管要求。系统日均处理交易量超过500万笔&#xff0c;峰值QPS达到3000&a…

ASP.NET Web 中进行 GET/POST 提交并接收返回数据的几种方案

在 ASP.NET Web 应用程序中进行 GET 请求并接收返回数据可以通过多种方式实现&#xff0c;以下是几种常见的方法&#xff1a; 1. 使用 WebClient 类&#xff08;简单方式&#xff09; using System.Net; using System.IO;public string GetDataFromUrl(string url) {using (W…

Springboot--Kafka客户端参数关键参数的调整方法

调整 Kafka 客户端参数需结合生产者、消费者和 Broker 的配置&#xff0c;以实现性能优化、可靠性保障或资源限制。以下是关键参数的调整方法和注意事项&#xff1a; 一、生产者参数调整 ‌max.request.size‌ ‌作用‌&#xff1a;限制单个请求的最大字节数&#xff08;包括消…

Android学习总结之service篇

引言 在 Android 开发里&#xff0c;Service 与 IntentService 是非常关键的组件&#xff0c;它们能够让应用在后台开展长时间运行的操作。不过&#xff0c;很多开发者仅仅停留在使用这两个组件的层面&#xff0c;对其内部的源码实现了解甚少。本文将深入剖析 Service 和 Inte…

ExternalProject_Add 使用手册与文档详解

一、基本概念与语法 ExternalProject_Add 是 CMake 的一个核心命令&#xff0c;用于在构建过程中集成和管理外部项目&#xff08;如第三方库&#xff09;。它支持完整的生命周期管理&#xff0c;包括下载、配置、构建、安装和测试。 语法&#xff1a; ExternalProject_Add(&l…

低延迟云网络的核心技术

低延迟云网络通过架构优化、协议创新、硬件加速等多维度技术手段,将数据传输延迟降低至毫秒级甚至微秒级。 1. 网络架构优化 1.1 扁平化网络Leaf-Spine 架构 减少网络层级,缩短数据转发路径(如数据中心内部一跳可达)。 扁平化网络Leaf-Spine(叶子-脊椎)架构是一种现代…

网络安全法规与入门指南

在当今数字化时代&#xff0c;网络安全已成为保障个人隐私、企业利益和国家安全的关键领域。随着网络攻击的日益复杂和频繁&#xff0c;了解和遵守网络安全法规变得尤为重要。本文将深入探讨网络安全相关法规&#xff0c;并为想要进入这一领域的读者提供实用的入门指南。 一、…

硬盘分区格式方案之 MBR(Master Boot Record)主引导记录的 主分区 和 扩展分区 笔记250407

硬盘分区格式方案之 MBR&#xff08;Master Boot Record&#xff09;主引导记录的 主分区 和 扩展分区 笔记250407 一、主分区&#xff08;Primary Partition&#xff09; 1. 定义与功能 直接引导操作系统&#xff1a;主分区是独立的存储单元&#xff0c;可直接安装操作系统并…

【Proteus仿真】【32单片机-A007】PT100热敏温度检测系统设计

目录 一、主要功能 二、使用步骤 三、硬件资源 四、软件设计 五、实验现象 联系作者 一、主要功能 1、LCD1602显示当前检测的温度值以及温度阈值 2、超过上限温度&#xff0c;降温模块启动​ 3、PT100热敏电阻测量-60C-135C 4、按键设置温度阈值 5、超过阈值&#xff0…

pyqt SQL Server 数据库查询-优化2

1、增加导出数据功能 2、增加删除表里数据功能 import sys import pyodbc from PyQt6.QtWidgets import QApplication, QWidget, QVBoxLayout, QHBoxLayout, QListWidget, QLineEdit, QPushButton, \QTableWidget, QTableWidgetItem, QLabel, QMessageBox from PyQt6.QtGui i…

Github 热点项目 ChartDB AI自动导表结构+迁移脚本,3分钟生成专业数据库关系图

ChartDB堪称数据库设计神器&#xff01;亮点①&#xff1a;动动手指输入SQL&#xff0c;秒出结构图&#xff0c;表关系一目了然&#xff0c;团队评审时再也不用画图两小时。亮点②&#xff1a;AI智能转换超贴心&#xff0c;MySQL转PostgreSQL只需点个按钮&#xff0c;跨平台迁移…

地质科研智能革命:当大语言模型“扎根”地质现场、大语言模型本地化部署与AI智能体协同创新实践

在地质学迈向“深时数字地球”&#xff08;Deep-time Digital Earth&#xff09;的进程中&#xff0c;传统研究方法正面临海量异构数据&#xff08;地质图件、遥感影像、地震波谱等&#xff09;的解析挑战。大语言模型&#xff08;LLM&#xff09;与AI智能体的本地化部署技术&a…

DAPP实战篇:使用web3.js连接合约

说明 本系列内容目录:专栏:区块链入门到放弃查看目录 如果你还没有创建好项目请先查看:《DApp实战篇:先用前端起个项目》,如果你还不知道web3.js是什么请先查看:《DApp实战篇:前端技术栈一览》。 安装 点此查看web3.js官方文档 打开项目根目录,并唤起终端: 键入w…

源代码保密解决方案

背景分析 随着各行各业业务数据信息化发展&#xff0c;各类产品研发及设计等行业&#xff0c;都有关乎自身发展的核心数据&#xff0c;包括业务数据、源代码保密数据、机密文档、用户数据等敏感信息&#xff0c;这些信息数据有以下共性&#xff1a; — 属于核心机密资料&…

dolphinscheduler单机部署链接oracle

部署成功请给小编一个赞或者收藏激励小编 1、安装准备 JDK版本:1.8或者1.8oracle版本&#xff1a;19Coracle驱动版本&#xff1a;8 2、安装jdk 下载地址&#xff1a;https://www.oracle.com/java/technologies/downloads/#java8 下载后上传到/tmp目录下。 然后执行下面命…