当前位置: 首页 > news >正文

手撕 视觉slam14讲 ch7 / pose_estimation_3d2d.cpp (1)

首先理清我们需要实现什么功能,怎么实现,提供一份整体逻辑:包括主函数和功能函数

主函数逻辑:

 1. 读图,两张rgb(cv::imread)

 2. 找到两张rgb图中的特征点匹配对

       2.1定义所需要的参数:keypoints1, keypoints2,matches

       2.2 提取每张图像的检测 Oriented FAST 角点位置并匹配筛选(调用功能函数1)

 3. 建立3d点(像素坐标到相机坐标)

        3.1读出深度图(cv::imread)

        3.2取得每个匹配点对的深度

                3.2.1 得到第y行,第x个像素的深度值

                   (ushort d = d1.ptr<unsigned short> (row)[column])

                3.2.2 去除没有深度的点

                3.2.3 转到相机坐标系(调用功能函数2)

4. 调用epnp求解(input:3d点,2d点对,内参,是否去畸变,求解方式)

        4.1求解(cv::solvePnP)

         4.2 求解结果为向量,需要转成矩阵(cv::Rodrigues)

int main( int agrc, char** agrv) {
//  1. 读图(两张rgb)Mat image1 = imread(agrv[1] , CV_LOAD_IMAGE_COLOR );Mat image2 = imread(agrv[2] , CV_LOAD_IMAGE_COLOR );assert(image1.data && image2.data && "Can not load images!");//  2. 找到两张rgb图中的特征点匹配对// 2.1定义keypoints1, keypoints2,matchesstd::vector<KeyPoint>keypoints1,keypoints2;std::vector<DMatch>matches;// 2.2 提取每张图像的检测 Oriented FAST 角点位置并匹配筛选Featurematcher(image1,image2, keypoints1,keypoints2,matches);//  3. 建立3d点(像素坐标到相机坐标)Mat K  = (Mat_<double>(3, 3) << 520.9, 0, 325.1, 0, 521.0, 249.7, 0, 0, 1);//内参vector<Point3f> pts_3d;vector<Point2f> pts_2d;//3.1读出深度图Mat d1 =imread(agrv[3],CV_LOAD_IMAGE_UNCHANGED);//3.2取得每个匹配点对的深度(ushort d = d1.ptr<unsigned short> (row)[column];就是指向d1的第row行的第column个数据。数据类型为无符号的短整型 )for (DMatch m: matches){//3.2.1 得到第y行,第x个位置的像素的深度值ushort d = d1.ptr<unsigned short>(int (keypoints1[m.queryIdx].pt.y)) [int(keypoints1[m.queryIdx].pt.x)];// 3.2.2 去除没有深度的点if(d==0){continue;}float dd=d/5000.0 ;//3.2.3 转到相机坐标系Point2d p1 = pixtocam(keypoints1[m.queryIdx].pt , K);pts_3d.push_back(Point3f(p1.x*dd,p1.y*dd,dd));pts_2d.push_back(keypoints2[m.trainIdx].pt);}cout << "3d-2d pairs: " << pts_3d.size() << endl;//  4. 调用epnp求解(input:3d点,2d点对,内参,false,求解方式)// solvePnP( InputArray objectPoints, InputArray imagePoints, InputArray cameraMatrix, InputArray distCoeffs, OutputArray rvec, OutputArray tvec, bool useExtrinsicGuess = false, int flags = SOLVEPNP_ITERATIVE );Mat r,t;// 4.1求解solvePnP(pts_3d,pts_2d,K,Mat(), r,t,false,SOLVEPNP_EPNP);// 4.2 求解结果为向量,需要转成矩阵Mat R;cv::Rodrigues(r,R);cout<<"R="<<R<<endl;cout<<"T="<<t<<endl;// 5.可视化匹配Mat img_goodmatch;drawMatches(image1, keypoints1, image2, keypoints2, matches, img_goodmatch);imshow("good matches", img_goodmatch);waitKey(0);return 0;
}

功能函数1:  Featurematcher

实现过程在前几篇中已经详细说明:视觉slam14讲 逐行解析代码 ch7 / orb_cv.cpp

2.2.1初始化存储特征点数据的变量

2.2.2 提取每张图像的检测 Oriented FAST 角点位置

2.2.3 计算图像角点的BRIEF描述子

2.2.4 根据刚刚计算好的BRIEF描述子,对两张图的角点进行匹配

2.2.5 匹配点对筛选计算最小距离和最大距离

2.2.6 当描述子之间的距离大于两倍的最小距离时,即认为匹配有误.但有时候最小距离会非常小,设置一个经验值30作为下限.

void Featurematcher( const Mat &image1, const Mat &image2, std::vector<KeyPoint>&keypoints1, std::vector<KeyPoint> &keypoints2,  std::vector<DMatch> &matches){// 2.2.1初始化存储特征点数据的变量Mat descr1, descr2;Ptr<FeatureDetector> detector = ORB::create();Ptr<DescriptorExtractor> descriptor = ORB::create();Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create("BruteForce-Hamming");// 2.2.2 提取每张图像的检测 Oriented FAST 角点位置detector->detect(image1, keypoints1);detector->detect(image2, keypoints2);// 2.2.3 计算图像角点的BRIEF描述子descriptor->compute(image1, keypoints1, descr1);descriptor->compute(image2, keypoints2, descr2);// 2.2.4 根据刚刚计算好的BRIEF描述子,对两张图的角点进行匹配std::vector<DMatch> match;matcher->match(descr1, descr2, match);Mat img_match;drawMatches(image1, keypoints1, image2, keypoints2, match, img_match);imshow("all matches", img_match);waitKey(0);// 2.2.5 匹配点对筛选计算最小距离和最大距离double min_dis = 10000, max_dis = 0;// 2.2.5.1找出所有匹配之间的最小距离和最大距离, 即是最相似的和最不相似的两组点之间的距离for (int i = 0; i < descr1.rows; i++){double dist = match[i].distance;if (dist < min_dis)min_dis = dist;if (dist > max_dis)max_dis = dist;}cout<<"max_dis="<<max_dis<<endl;cout<<"min_dis="<<min_dis<<endl;//2.2.6 当描述子之间的距离大于两倍的最小距离时,即认为匹配有误.但有时候最小距离会非常小,设置一个经验值30作为下限.for (int i = 0; i < descr1.rows; i++){if (match[i].distance<= max(2*min_dis,30.0)){matches.push_back(match[i]);}       }cout<<"matches.size="<<matches.size()<<endl;
}

功能函数2:

将输入的像素坐标(x ,y)转化到归一化相机坐标系下得到(X,Y)

我们知道:相机的投影模型为:u=KP, 即

\begin{bmatrix} x \\ y \\ 1 \end{bmatrix}=\begin{bmatrix} f_{x} &0&c_x\\ 0&f_y&c_y\\ 0&0&1 \end{bmatrix} \begin{bmatrix} X \\ Y \\ 1 \end{bmatrix}

所以 X=(x-c_x)/f_x     ,    Y=(y-c_y)/f_y

Point2d pixtocam(const  Point2d &p ,  const Mat  &K){return Point2d(// X=(u-cx)/fx(p.x - K.at<double>(0,2)) / K.at<double>(0,0) ,// Y=(v-cy)/fy(p.y-K.at<double>(1,2)) / K.at<double>(1,1));
}

最后匹配效果及位姿结果:

allmatch:

goodmatch:

位姿输出:R,T:

相关文章:

手撕 视觉slam14讲 ch7 / pose_estimation_3d2d.cpp (1)

首先理清我们需要实现什么功能&#xff0c;怎么实现&#xff0c;提供一份整体逻辑&#xff1a;包括主函数和功能函数 主函数逻辑&#xff1a; 1. 读图,两张rgb&#xff08;cv::imread&#xff09; 2. 找到两张rgb图中的特征点匹配对 2.1定义所需要的参数&#xff1a;keypoints…...

Mac安装Dart时,Homebrew报错 Error: Failure while executing

前言&#xff1a; 最近准备开发Flutter项目时&#xff0c;在安装环境时&#xff0c;安装Homebew时遇到了以下报错信息&#xff0c;在这里分享一下。 报错信息&#xff1a; ~ % brew tap dart-lang/dart > Tapping dart-lang/dart Cloning into /opt/homebrew/Library/Tap…...

SSM整合~

构建并配置项目&#xff1a; 第一步&#xff1a;创建maven项目 第二步&#xff1a;配置pom.xml文件 设置打包方式&#xff1a; 为了方便部署&#xff0c;我们通常情况下&#xff0c;将项目打包为WAR&#xff0c;因为WAR文件是一种可执行的压缩文件&#xff0c;它可以将项目…...

Self-supervised 3D Human Pose Estimation from a Single Image

基于单幅图像的自监督三维人体姿态估计 主页&#xff1a; https://josesosajs.github.io/ imagepose/ 源码&#xff1a;未开源 摘要 我们提出了一种新的自我监督的方法预测三维人体姿势从一个单一的图像。预测网络是从描绘处于典型姿势的人的未标记图像的数据集和一组未配对…...

ubuntu下cups部分场景

第一章&#xff1a;部分操作指令 在计算机领域中&#xff0c;cups 是“通用UNIX打印系统”&#xff08;Common UNIX Printing System&#xff09;的缩写&#xff0c;它是一种用于在UNIX-like操作系统上管理打印任务的开源打印系统。cups 提供了一个框架&#xff0c;允许用户和…...

通过geoserver imageMosic发布多张tif数据

通过geoserver imageMosic发布多张tif数据 reference: https://zhuanlan.zhihu.com/p/132388558 https://zhuanlan.zhihu.com/p/103674876 https://docs.geoserver.org/latest/en/user/tutorials/imagemosaic_timeseries/imagemosaic_timeseries.html 步骤 下载数据 http…...

输出图元(四)8-2 OpenGL画点函数、OpenGL画线函数

4.3 OpenGL画点函数 要描述一个点的几何要素&#xff0c;我们只需在世界坐标系中指定一个位置。然后该坐标位置和场景中已有的其他几何描述一起被传递给观察子程序。除非指定其他属性值&#xff0c;OpenGL 图元按默认的大小和颜色来显示。默认的图元颜色是白色&#x…...

java八股文

6. 如何保证消息的可靠性&#xff1f; 在RabbitMq的整个消息投递过程中&#xff0c;有三种情况下&#xff0c;会存在消息丢失的问题&#xff1a; 6. RabbitMq如何保证消息的可靠性&#xff1f; 所以从这三个维度保证消息的可靠性去可靠性传递就可以了&#xff0c;从生产者发送…...

算法通关村——解析堆的应用

在数组中找第K大的元素 LeetCode21 Medium 我们要找第 K 大的元素&#xff0c;如果我们找使用大堆的话那么就会造成这个堆到底需要多大的&#xff0c;而且哪一个是第 K 的的元素我们不知道是哪一个索引&#xff0c;我们更想要的结果就是根节点就是我们要找的值&#xff0c;所以…...

爬虫源码---爬取小猫猫交易网站

前言&#xff1a; 本片文章主要对爬虫爬取网页数据来进行一个简单的解答&#xff0c;对与其中的数据来进行一个爬取。 一&#xff1a;环境配置 Python版本&#xff1a;3.7.3 IDE:PyCharm 所需库&#xff1a;requests &#xff0c;parsel 二&#xff1a;网站页面 我们需要…...

Python的由来和基础语法(一)

目录 一、Python 背景知识 1.1Python 是咋来的? 1.2Python 都能干啥? 1.3Python 的优缺点 二、基础语法 2.1常量和表达式 2.2变量和类型 变量的语法 (1) 定义变量 (2) 使用变量 变量的类型 (1) 整数 (2) 浮点数(小数) (3) 字符串 (4) 布尔 (5) 其他 动态类型…...

使用maven创建springboot项目

创建maven快速启动项目 命令行或者idea、eclipse快捷创建也可以 pom.xml下project项目下导入springboot 父工程 <!--导入springboot 父工程--> <parent><artifactId>spring-boot-starter-parent</artifactId><groupId>org.springframework.bo…...

MySQL 基本操作1

目录 Create insert 插入跟新 1 插入跟新 2 Retrive select where 子句查询 1.查找数学成绩小于 80 的同学。 2.查询数学成绩等于90分的同学。 3.查询总分大于240 的学生 4.查询空值或者非空值 5.查询语文成绩在70~80之间的同学 6.查询英语成绩是99 和 93 和 19 和…...

linux内网yum源服务器搭建

1.nginx: location / {root /usr/local/Kylin-Server-V10-SP3-General-Release-2303-X86_64;autoindex on;autoindex_localtime on;autoindex_exact_size off; } 注:指定到镜像的包名 2.修改yum源地址 cd /etc/yum.repos.d/vim kylin_x86_64.repo 注: --enabled设置为1 3.重…...

机器学习与数据分析

【数据清洗】 异常检测 孤立森林&#xff08;Isolation Forest&#xff09;从原理到实践 效果评估&#xff1a;F-score 【1】 保护隐私的时间序列异常检测架构 概率后缀树 PST – &#xff08;异常检测&#xff09; 【1】 UEBA架构设计之路5&#xff1a; 概率后缀树模型 【…...

项目总结知识点记录-文件上传下载(三)

&#xff08;1&#xff09;文件上传 代码&#xff1a; RequestMapping(value "doUpload", method RequestMethod.POST)public String doUpload(ModelAttribute BookHelper bookHelper, Model model, HttpSession session) throws IllegalStateException, IOExcepti…...

基于LinuxC语言实现的TCP多线程/进程服务器

多进程并发服务器 设计流程 框架一&#xff08;使用信号回收僵尸进程&#xff09; void handler(int sig) {while(waitpid(-1, NULL, WNOHANG) > 0); }int main() {//回收僵尸进程siganl(17, handler);//创建服务器监听套接字 serverserver socket();//给服务器地址信息…...

浅谈JVM垃圾回收机制

一、HotSpot VM中的GC分为两大类 1.部分收集(Partial GC): 新生代收集(Minor GC/Young GC):只对新生代进行垃圾收集老年代收集(Major GC/Old GC):只队老年代进行垃圾收集混合收集(Mixed GC):对整个新生代和老年代进行垃圾收集 2.整堆收集(Full GC) 收集整个Java堆和方法区 …...

【80天学习完《深入理解计算机系统》】第十二天3.6数组和结构体

专注 效率 记忆 预习 笔记 复习 做题 欢迎观看我的博客&#xff0c;如有问题交流&#xff0c;欢迎评论区留言&#xff0c;一定尽快回复&#xff01;&#xff08;大家可以去看我的专栏&#xff0c;是所有文章的目录&#xff09;   文章字体风格&#xff1a; 红色文字表示&#…...

基于Python+OpenCV智能答题卡识别系统——深度学习和图像识别算法应用(含Python全部工程源码)+训练与测试数据集

目录 前言总体设计系统整体结构图系统流程图 运行环境Python 环境PyCharm安装OpenCV环境 模块实现1. 信息识别2. Excel导出模块3. 图形用户界面模块4. 手写识别模块 系统测试1. 系统识别准确率2. 系统识别应用 工程源代码下载其它资料下载 前言 本项目基于Python和OpenCV图像处…...

java_网络服务相关_gateway_nacos_feign区别联系

1. spring-cloud-starter-gateway 作用&#xff1a;作为微服务架构的网关&#xff0c;统一入口&#xff0c;处理所有外部请求。 核心能力&#xff1a; 路由转发&#xff08;基于路径、服务名等&#xff09;过滤器&#xff08;鉴权、限流、日志、Header 处理&#xff09;支持负…...

VB.net复制Ntag213卡写入UID

本示例使用的发卡器&#xff1a;https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...

day52 ResNet18 CBAM

在深度学习的旅程中&#xff0c;我们不断探索如何提升模型的性能。今天&#xff0c;我将分享我在 ResNet18 模型中插入 CBAM&#xff08;Convolutional Block Attention Module&#xff09;模块&#xff0c;并采用分阶段微调策略的实践过程。通过这个过程&#xff0c;我不仅提升…...

MVC 数据库

MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用

文章目录 问题现象问题原因解决办法 问题现象 macOS启动台&#xff08;Launchpad&#xff09;多出来了&#xff1a;Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显&#xff0c;都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

python如何将word的doc另存为docx

将 DOCX 文件另存为 DOCX 格式&#xff08;Python 实现&#xff09; 在 Python 中&#xff0c;你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是&#xff0c;.doc 是旧的 Word 格式&#xff0c;而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

基于Docker Compose部署Java微服务项目

一. 创建根项目 根项目&#xff08;父项目&#xff09;主要用于依赖管理 一些需要注意的点&#xff1a; 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件&#xff0c;否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...

无人机侦测与反制技术的进展与应用

国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机&#xff08;无人驾驶飞行器&#xff0c;UAV&#xff09;技术的快速发展&#xff0c;其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统&#xff0c;无人机的“黑飞”&…...

0x-3-Oracle 23 ai-sqlcl 25.1 集成安装-配置和优化

是不是受够了安装了oracle database之后sqlplus的简陋&#xff0c;无法删除无法上下翻页的苦恼。 可以安装readline和rlwrap插件的话&#xff0c;配置.bahs_profile后也能解决上下翻页这些&#xff0c;但是很多生产环境无法安装rpm包。 oracle提供了sqlcl免费许可&#xff0c…...

【Kafka】Kafka从入门到实战:构建高吞吐量分布式消息系统

Kafka从入门到实战:构建高吞吐量分布式消息系统 一、Kafka概述 Apache Kafka是一个分布式流处理平台,最初由LinkedIn开发,后成为Apache顶级项目。它被设计用于高吞吐量、低延迟的消息处理,能够处理来自多个生产者的海量数据,并将这些数据实时传递给消费者。 Kafka核心特…...