【opencv】教程代码 —features2D(8)AKAZE 特征点匹配和图像拼接

6984768f6e261b85fe9f8864dba8ffc9.png

graf1.png

a6f744ec5f12bf315c07be46170c0e6e.png

graf3.png

<?xml version="1.0"?>
<opencv_storage>
<H13 type_id="opencv-matrix"><rows>3</rows><cols>3</cols><dt>d</dt><data>7.6285898e-01  -2.9922929e-01   2.2567123e+023.3443473e-01   1.0143901e+00  -7.6999973e+013.4663091e-04  -1.4364524e-05   1.0000000e+00 </data></H13>
</opencv_storage>

H1to3p.xml

AKAZE_match.cpp 特征点匹配和图像拼接

172f40189ba94a156e6747c7c2afe9a8.png

6582d0545d042293fc0efda481f96439.png

此代码为功能强大的特征点匹配和图像拼接程序,主要使用OPENCV库的AKAZE算法。流程如下:

  1. 读取两张图片及齐次图矩阵。

  2. 利用AKAZE算法提取图像的特征点和描述子

  3. 使用Brute-Force匹配器,对两组描述子执行近邻搜索,找出最佳匹配对。

  4. 进行比率测试来剔除不良匹配

  5. 利用齐次图矩阵验证匹配点,筛选出内点

    我们对之前通过比例测试找到的匹配点对进行进一步的同质性检查,通过计算变换后的点与原始匹配点之间的欧氏距离来评估匹配质量。如果点对对应的变换后的距离小于设定的内点阈值,这对点匹配就被认定为好的匹配,并分别添加到内点向量inliers1inliers2和良好匹配向量good_matches中。最终,good_matches中包含了所有通过同质性检查的内点匹配对,可以用于后续绘制匹配结果或其他处理。

  6. 绘制和保存匹配点的结果图片

  7. 打印关于匹配的统计信息,并显示结果。

整个代码实现的是对两张图片进行特征点匹配,并通过一定的筛选条件去除错误的匹配点,最后绘制出内点并计算内点比例

#include <opencv2/features2d.hpp> // 引入OpenCV特征检测相关头文件
#include <opencv2/imgproc.hpp>    // 引入OpenCV图像处理相关头文件
#include <opencv2/highgui.hpp>    // 引入OpenCV高级GUI(图形用户界面)相关头文件
#include <iostream>               // 引入输入输出流头文件using namespace std; // 使用标准命名空间
using namespace cv;  // 使用OpenCV命名空间const float inlier_threshold = 2.5f; // 设置内点距离阈值,用于同质性检查识别内点
const float nn_match_ratio = 0.8f;   // 设置最近邻匹配比例int main(int argc, char* argv[])
{//! [load]// 解析命令行参数CommandLineParser parser(argc, argv,"{@img1 | graf1.png | input image 1}""{@img2 | graf3.png | input image 2}""{@homography | H1to3p.xml | homography matrix}");// 读取图片1,以灰度模式Mat img1 = imread( samples::findFile( parser.get<String>("@img1") ), IMREAD_GRAYSCALE);// 读取图片2,以灰度模式Mat img2 = imread( samples::findFile( parser.get<String>("@img2") ), IMREAD_GRAYSCALE);// 读取同质性矩阵Mat homography;FileStorage fs( samples::findFile( parser.get<String>("@homography") ), FileStorage::READ);fs.getFirstTopLevelNode() >> homography;//! [load]//! [AKAZE]// 初始化特征点向量和描述符矩阵vector<KeyPoint> kpts1, kpts2;Mat desc1, desc2;// 创建AKAZE特征检测器Ptr<AKAZE> akaze = AKAZE::create();// 对img1进行特征检测和描述符计算akaze->detectAndCompute(img1, noArray(), kpts1, desc1);// 对img2进行特征检测和描述符计算akaze->detectAndCompute(img2, noArray(), kpts2, desc2);//! [AKAZE]//! [2-nn matching]// 创建BFMatcher,用于特征匹配BFMatcher matcher(NORM_HAMMING);vector< vector<DMatch> > nn_matches;// 执行2近邻匹配matcher.knnMatch(desc1, desc2, nn_matches, 2);//! [2-nn matching]//! [ratio test filtering]// 初始化过滤后的匹配特征点向量vector<KeyPoint> matched1, matched2;// 过滤不符合比例测试的匹配for(size_t i = 0; i < nn_matches.size(); i++) {DMatch first = nn_matches[i][0];float dist1 = nn_matches[i][0].distance;float dist2 = nn_matches[i][1].distance;// 如果第一个距离小于第二个距离乘以设定的比例,则认为是好的匹配if(dist1 < nn_match_ratio * dist2) {matched1.push_back(kpts1[first.queryIdx]);matched2.push_back(kpts2[first.trainIdx]);}}//! [ratio test filtering]//! [homography check]vector<DMatch> good_matches; // 初始化一个DMatch向量,用于存储良好匹配对vector<KeyPoint> inliers1, inliers2; // 初始化两个KeyPoint向量,用于存储一致性检查后的内点匹配// 遍历所有已匹配的特征点对for(size_t i = 0; i < matched1.size(); i++) {Mat col = Mat::ones(3, 1, CV_64F); // 创建一个三行一列的矩阵,初始化为1,用于齐次坐标表示col.at<double>(0) = matched1[i].pt.x; // 设置矩阵的第一个元素为当前匹配对的第一个点的x坐标col.at<double>(1) = matched1[i].pt.y; // 设置矩阵的第二个元素为当前匹配对的第一个点的y坐标col = homography * col; // 通过同质性矩阵变换第一个点的坐标col /= col.at<double>(2); // 使变换后的坐标成为非齐次坐标// 计算两个匹配点之间的欧氏距离double dist = sqrt( pow(col.at<double>(0) - matched2[i].pt.x, 2) +pow(col.at<double>(1) - matched2[i].pt.y, 2));// 如果距离小于内点阈值,则认为这个匹配是好的内点匹配if(dist < inlier_threshold) {int new_i = static_cast<int>(inliers1.size()); // 计算当前内点的索引inliers1.push_back(matched1[i]); // 将第一个点添加到内点集中inliers2.push_back(matched2[i]); // 将第二个点添加到内点集中good_matches.push_back(DMatch(new_i, new_i, 0)); // 将这对内点添加到良好匹配向量中}}//! [homography check]//! [draw final matches]// 初始化结果图像Mat res;// 绘制好的匹配点对drawMatches(img1, inliers1, img2, inliers2, good_matches, res);// 保存结果图像imwrite("akaze_result.png", res);// 计算内点比率double inlier_ratio = inliers1.size() / (double) matched1.size();// 输出统计结果cout << "A-KAZE Matching Results" << endl;cout << "*******************************" << endl;cout << "# Keypoints 1:                        \t" << kpts1.size() << endl;cout << "# Keypoints 2:                        \t" << kpts2.size() << endl;cout << "# Matches:                            \t" << matched1.size() << endl;cout << "# Inliers:                            \t" << inliers1.size() << endl;cout << "# Inliers Ratio:                      \t" << inlier_ratio << endl;cout << endl;// 显示结果图像imshow("result", res);// 等待用户响应waitKey();//! [draw final matches]return 0;
}

终端输出:

A-KAZE Matching Results
*******************************
# Keypoints 1:                          2418
# Keypoints 2:                          2884
# Matches:                              382
# Inliers:                              267
# Inliers Ratio:                        0.698953

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

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

相关文章

matlab碰撞检测

文章目录 碰撞对象collisionCylindercollisionBoxcollisionMeshcollisionSpherecollisionCapsulecheckCollisionfitCollisionCapsuleshowCollisionArraycapsuleApproximationaddCapsuleremoveCapsuleconvertToCollisionMesh碰撞对象 函数功能checkCollision检测两几何体是否存在…

前端之CSS——网页的皮肤!!

目录 一、CSS简单介绍 二、css内容 2.1 css的编写方式 2.2 css选择器 2.3 样式属性 2.4 css包围盒 2.5 css中的display 2.6 css中的定位 2.7 css中的浮动与清除 2.7 弹性容器 2.8 字体图标 2.9 …

1.5编写一个程序,输入梯形的上底,下底和高,输出梯形的面积。

1、编写一个程序,输入梯形的上底,下底和高,输出梯形的面积。 package com.kangning.web.controller.system;import java.util.Scanner;/*** 编写一个程序,输入梯形的上底,下底和高,输出梯形的面积。*/ public class CountArea {public static void main(String[] args) …

面向对象编程中的StringBuffer类详解

咦咦咦&#xff0c;各位小可爱&#xff0c;我是你们的好伙伴——bug菌&#xff0c;今天又来给大家普及Java SE相关知识点了&#xff0c;别躲起来啊&#xff0c;听我讲干货还不快点赞&#xff0c;赞多了我就有动力讲得更嗨啦&#xff01;所以呀&#xff0c;养成先点赞后阅读的好…

【Linux 驱动基础】设备树驱动

# 前置知识 在图中&#xff0c;树的主干就是系统总线&#xff0c; IIC 控制器、 SPI 控制器等都是接到系统主线上的分支。其中 IIC1 上接了 AT24C02这个 IIC 设备&#xff0c; DTS 文件的主要功能就是按照图所示的结构来描述板子上的设备信息。 1. Device格式 DTS文件格式 …

【论文阅读】ELA: Efficient Local Attention for Deep Convolutional Neural Networks

&#xff08;ELA&#xff09;Efficient Local Attention for Deep Convolutional Neural Networks 论文链接&#xff1a;ELA: Efficient Local Attention for Deep Convolutional Neural Networks (arxiv.org) 作者&#xff1a;Wei Xu, Yi Wan 单位&#xff1a;兰州大学信息…

基于架构的软件开发方法_1.概述和相关概念及术语

1.体系结构的设计方法概述 基于体系结构的软件设计&#xff08;Architecture-Based Software Design&#xff0c;ABSD&#xff09;方法。ABSD方法是由体系结构驱动的&#xff0c;即指由构成体系结构的商业、质量和功能需求的组合驱动的。 使用ABSD方法&#xff0c;设计活动可以…

C++项目——集群聊天服务器项目(十一)服务器异常退出与添加好友业务

本节来实现C集群聊天服务器项目中的服务器异常退出与添加好友业务&#xff0c;一起来试试吧 一、服务器异常退出 在Linux环境下&#xff0c;我们在服务器端使用CTRLC结束程序执行&#xff0c;即使用CTRLC让服务器异常退出&#xff0c;这样的后果是本应登录服务器的用户在数据库…

vsCode 刷 leetcode 使用 Cookie 登录

1. 安装插件 打开 vsCode&#xff0c;选择扩展&#xff0c;搜索 leetcode&#xff0c;选择第一个&#xff0c;带有中文力扣字样&#xff0c;安装后重启 2. 切换终端 插件安装成功之后&#xff0c;侧边栏选择 leetcode 菜单&#xff0c;切换终端&#xff0c;选择中文版本&…

海康摄像头插件嵌入iframe时视频播放插件位置问题

参考&#xff1a;https://juejin.cn/post/6857670423971758094 原因&#xff1a;没有按照iframe相对位置计算视频插件位置。 解决&#xff1a; $(window).on(resize, resize);function resize(){// 解决iframe中嵌入海康插件初始化问题:// 1. 获取iframe相比于窗口的偏移量;c…

Flutter仿Boss-2.启动页、引导页

简述 在移动应用开发中&#xff0c;启动页和引导页是用户初次接触应用时的重要组成部分&#xff0c;能够提升用户体验和导航用户了解应用功能。本文将介绍如何使用Flutter实现启动页和引导页&#xff0c;并展示相关代码实现。 启动页 启动页是应用的第一个页面&#xff0c;首…

Jenkins首次安装选择推荐插件时出现”No such plugin cloudbees-folder”解决方案

安装Jenkins成功之后&#xff0c;首次启动Jenkins后台管理&#xff0c;进入到安装插件的步骤&#xff0c;选择"推荐安装"&#xff0c;继续下一步的时候出现错误提示&#xff1a; 出现一个错误 安装过程中出现一个错误&#xff1a;No such plugin&#xff1a;cloudb…

【大数据存储】实验二 HDFS操作实验

实验二 HDFS操作实验 启动Hadoop&#xff0c;执行jps&#xff0c;检查Hadoop相关进程是否启动成功 启动hadoop 执行jps,可以看到名称节点和数据节点&#xff0c;第二名称节点都打开了&#xff0c;则hadoop相关进程启动成功 在本地文件系统“/home”下新建两个文件夹&#xff…

Dapr(一) 基于云原生了解Dapr

(这期先了解Dapr&#xff0c;之后在推出如何搭建Dapr&#xff0c;以及如何使用。) 目录 引言&#xff1a; Service Mesh定义 Service Mesh解决的痛点 Istio介绍 Service Mesh遇到的挑战 分布式应用的需求 Multiple Runtime 理念推导 Dapr 介绍 Dapr 特性 Dapr 核心…

前后台分离nodejs+vue租房信息网站express-94sk3.

本租房管理系统有管理员&#xff0c;租客&#xff0c;屋主三个角色。管理员功能有个人中心&#xff0c;租客管理&#xff0c;屋主管理&#xff0c;房源信息管理&#xff0c;订单信息管理&#xff0c;屋主申诉管理&#xff0c;通知公告管理&#xff0c;留言板管理&#xff0c;系…

Electron的学习

目录 项目初始化可以看官网非常详细根路径创建.vscode文件夹主进程和渲染进程之前的通信ipcRenderer.send和ipcMain.on的使用ipcRenderer.invoke和ipcMain.handle的使用 切换主题模式文件拖放保存消息通知进度展示图标闪烁自定义菜单自定义右键菜单 项目初始化可以看官网非常详…

基于PSO优化的CNN-LSTM-Attention的时间序列回归预测matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1卷积神经网络&#xff08;CNN&#xff09;在时间序列中的应用 4.2 长短时记忆网络&#xff08;LSTM&#xff09;处理序列依赖关系 4.3 注意力机制&#xff08;Attention&#xff09; 5…

如何将平板或手机作为电脑的外接显示器?

先上官网链接&#xff1a;ExtensoDesk 家里有一台华为平板&#xff0c;自从买回来以后除了看视频外&#xff0c;基本没什么作用&#xff0c;于是想着将其作为我电脑的第二个屏幕&#xff0c;提高我学习办公的效率&#xff0c;废物再次利用。最近了解到华为和小米生态有多屏协同…

FMEA引领智能家居安全革新,打造无忧智能生活新纪元!

在智能家居日益普及的今天&#xff0c;如何确保家居安全成为消费者关注的焦点。本文将探讨如何通过FMEA&#xff08;故障模式与影响分析&#xff09;这一强大的质量管理工具&#xff0c;为智能家居赋能&#xff0c;打造安全无忧的智能生活新体验。 一、FMEA在智能家居领域的应用…

wireshark数据流分析-学习日记day1

参考内容&#xff1a; 网址hxxp://194.55.224[.]9/liuz/5/fre.php描述Loki Bot C2 网址早在 2023-08-15 就被注意到了2023-07-27 记录的 IcedID C2 域&#xff1a; vrondafarih[.]com - HTTP trafficmagiketchinn[.]com - HTTPS trafficmagizanqomo[.]com - HTTPS traffic 网…