opencv中solvePnPRansac函数求解相机位姿

2023-05-16

PnP(Perspective n Points):2D—3D,求解相机位姿

PnP(Perspective n Points)就是你有n个点的3D位置和它们的投影,然后要算相机的位姿。这个倒是SLAM里最常见的情况,因为你会有一堆的地图点和像素点等着你算。PnP的做法有好多种:直接线性变换,P3P,EPnP,UPnP等等,基本你去找OpenCV的SolvePnP中的参数即可,好用的都在那里。除此之外,通常认为线性方程解PnP,在有噪声的情况下表现不佳,所以一般以EPnP之类的解为初始值,构建一个Bundle Adjustment(BA)去做优化。


一、函数介绍


源码位置:An example of how to use solvePNPRansac for object detection can be found at opencv_source_code/samples/cpp/tutorial_code/calib3d/real_time_pose_estimation/


二、例子

 cv::Mat rvec = cv::Mat::zeros(3, 1, CV_32FC1);          // output rotation vector
 cv::Mat tvec = cv::Mat::zeros(3, 1, CV_32FC1); 

// RANSAC parameters
int iterationsCount = 300;      // number of Ransac iterations.
float reprojectionError = 5.991;  // maximum allowed distance to consider it an inlier.
double confidence = 0.95;        // ransac successful confidence.

cv::Mat inliers;


//vector<Point3f> vPt3D;// 世界坐标:x=(u-u0)*depth/fx; y = (v-v0)*depth/fy; z=depth; (去除深度值不存在的点对,顺序必须一致)

//vector<Point2f> vPt2D;//像素坐标,不需要归一化,会受噪声影响

bool b = solvePnPRansac(vPt3D, vPt2D, K, DistCoef, rvec, tvec, false, iterationsCount, reprojectionError, confidence, inliers, SOLVEPNP_ITERATIVE);   //点对个数必须大于4


cout<<"pnp OK="<<b<<", inliers point num="<<inliers.rows<<endl;

最后我们从旋转向量rvec和平移向量tvec得到变换矩阵,该代码的运行需要有opencv、Eigen库的支持。不然会出现计算的R、t数值很大,Rcw;相机坐标到世界坐标的转换)

//1.首先通过罗德里格斯变换将旋转向量rvec转换成3*3的旋转矩阵r
cv::Mat R;
cv::Rodrigues(rvec, R);
Eigen::Matrix3d r;
cv::cv2eigen(R, r);

//2.然后将平移向量tvec和旋转矩阵r转换成变换矩阵T(M2 = T*M1)
Eigen::Isometry3d T = Eigen::Isometry3d::Identity();
Eigen::AngleAxisd angle(r);
Eigen::Translation<double, 3> trans(tvec.at<double>(0), tvec.at<double>(1), tvec.at<double>(2));

  


  
T = angle;  //3*4
 T(0,3) = tvec.at<double>(0,0);
 T(1,3) = tvec.at<double>(1,0);
 T(2,3) = tvec.at<double>(2,0);

 Eigen::Quaterniond q(r);//四元数   

cout << "q:" << q.x() << " " << q.y() << " " << q.z() << " " << q.w() << endl; 

double w = q.x();   

double x = q.y();   

double y = q.z();   

double z = q.w();  

double a1 = atan2(2*(w*x+y*z),1-2*(x*x+y*y))*180/CV_PI;//旋转角度   ,绕x轴旋转

double a2 = asin(2*(w*y-z*x))*180/CV_PI;//绕y轴旋转

double a3 = atan2(2*(w*z+x*y), 1-2*(y*y+z*z))*180/CV_PI;  

cout<<"a1="<<a1<<", a2="<<a2<<",a3="<<a3<<endl; 


备注:

//3.求解变换矩阵T的逆矩阵temp
T = angle.inverse();
Eigen::Matrix<double,3,1> t;
cv::cv2eigen(tvec, t);
t = -1 * angle.inverse().matrix() *t;
T(0, 3) = t(0);
T(1, 3) = t(1);
T(2, 3) = t(2);
Eigen::Matrix<double, 4, 4> temp = Eigen::Matrix<double, 4, 4>::Zero();
for (int i = 0; i < 3; ++i){
    for (int j = 0; j < 4; ++j){
        temp(i, j) = T(i, j);
    }
}
temp(3, 0) = 0;
temp(3, 1) = 0;
temp(3, 2) = 0;
temp(3, 3) = 1;

补充知识:

摄像机坐标系中,摄像机在原点,x轴向右,z轴向前(朝向屏幕内或摄像机方向),y轴向上(不是世界的上方而是摄像机本身的上方)。


 cv::Mat Rwc = Tcw.rowRange(0,3).colRange(0,3).t();
   cv::Mat twc = -Rwc*Tcw.rowRange(0,3).col(3);


参考文献:

http://blog.csdn.net/gxsheen/article/details/52636852 (R、t向量转换成变换矩阵)

http://www.cnblogs.com/gaoxiang12/p/4669490.html (例子)

http://blog.csdn.net/cp32212116/article/details/38705297 (四元数、旋转角度)

http://docs.opencv.org/3.1.0/d9/d0c/group__calib3d.html#ga50620f0e26e02caa2e9adc07b5fbf24e (函数说明)

https://www.zhihu.com/question/51510464/answer/132196916 (2D-3D 2D-2D等求位姿方法)


  

  

  

  
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

opencv中solvePnPRansac函数求解相机位姿 的相关文章

  • 使用Android Studio打包Module成jar包

    现在假设我们想打包一个module成jar包的形式给其它应用调用 xff1a vrservice 1 0 jar 步骤1 在Module项目的build gradle文件中做如下配置 xff1a 生成jar包的配置如下 xff1a def
  • C++无符号整型与有符号整型变量的运算-不简单

    示例分析 xff1a include lt iostream gt include lt stdio h gt struct Result char c char d unsigned char e Result getChar int x
  • C++虚继承下的类大小

    前言 带有虚函数的虚继承的对象模型比较复杂 xff0c 所以单独整理一下 其实关于计算类大小是C 43 43 的一大易错点之一 即便是我在这儿理了半天 xff0c 也不一定就是正确的 xff0c 如果大佬看到本文 xff0c 发现我很多错误
  • 解决android的跑马灯频繁刷新的问题

    先贴一下跑马灯效果的代码 xff0c 这里我是继承的TextView xff1a public class MarqueeTextView extends AppCompatTextView public MarqueeTextView C
  • 关于第一次将STM32与电脑连接情况

    安装了Keil xff08 ARM xff09 版本之后 xff0c 不管是自己编程 xff0c 还是配套的程序运行 我们都想把它下载到STM32芯片里面 xff0c 在板子上运行 这里介绍几种方法 1 用J LINK下载调试 这个工具 x
  • [java语言]——InetAddress类的getByName()方法

    InetAddress 表示互联网协议 xff08 IP xff09 地址 InetAddress getByName 34 www 163 com 34 在给定主机名的情况下确定主机的IP地址 如果参数为null 获得的是本机的IP地址
  • Java中Calendar.DAY_OF_WEEK、DAY_OF_MONTH需要减一的原因

    Java中对日期的处理需要用到Calendar类 xff0c 其中有几个方法在使用时需要新手注意 1 在获取月份时 xff0c Calendar MONTH 43 1 的原因 xff08 Java中Calendar MONTH返回的数值其实
  • C语言学习笔记(三)(头文件的结构顺序)(类型不完整的解决方法)

    目录 前言原则结构推荐结构图方便的结构 类型不完整的原因和解决方法 xff1a 定义了不定长数组结构体的定义放在了头文件里面解决方法1 xff08 当采用使用时包含特定头文件时 xff09 xff1a 解决方法2 xff08 当一个头文件包
  • S2

    int count 61 0 double lat 61 55 8241 double lng 61 137 8347 double radius 61 900 半径 double capHeight 61 2 S2 M PI radius
  • 从STM32F407到AT32F407(一)

    雅特力公司的MCU有着性能超群 xff0c 价格优越的巨大优势 xff0c 缺点是相关资料少一些 xff0c 我们可以充分利用ST的现有资源来开发它 我用雅特力的STM32F437开发板 xff0c 使用原子 stm32f407的开发板自带
  • vue-java分离

    import com google gson Gson import io renren common utils HttpContextUtils import io renren common utils R import org ap
  • java学习

    莫求全 有效努力 定时出结果 架构设计DDD 微服务介绍 https www kancloud cn qingshou aaa1 2667225 https www cnblogs com chencan p 16042197 html h
  • CentOS6.5添加虚拟IP(VIP)

    使用keepalived 实现Nginx高可用时 需要用到这项技术 虚拟ip在高可用中的作用后续再说 今天看看怎么给服务器配置虚拟IP xff0c 其实也就是多分配个IP地址 首先查看一下现有网卡的IP地址 xff0c 用root特权运行下
  • 微服务Spring Cloud例子

    Spring Cloud简介 Spring Cloud是一个基于Spring Boot实现的云应用开发工具 xff0c 为开发者提供了在分布式系统 xff08 配置管理 xff0c 服务发现 xff0c 熔断 xff0c 路由 xff0c
  • 美邦威集成呼吸墙饰

    http www mbwqs cn 湖北光大新型环保装饰材料有限公司 美邦威集成呼吸墙饰 生产销售中心 xff1a 湖北汉川经济开发区光大工业园 光大材料 210590 上海股交所挂牌
  • activemq--MASTER SLAVE+BROKER CLUSTER 实践(二)

    鱼与熊掌兼得法 完美解决方案 我们知道 xff1a master slave模式下 xff0c 消息会被逐个复制而cluster模式下 xff0c 请求会被自动派发 那么可不可以把两者集成起来呢 xff1f 答案是有的 xff0c 网上所谓
  • Dubbo超时和重连机制

    dubbo启动时默认有重试机制和超时机制 超时机制的规则是如果在一定的时间内 xff0c provider没有返回 xff0c 则认为本次调用失败 xff0c 重试机制在出现调用失败时 xff0c 会再次调用 如果在配置的调用次数内都失败
  • Sharding-JDBC简介

    一般 xff0c 线上系统的业务量不是很大 xff0c 比如说单库的数据量在百万级别以下 xff0c 那么MySQL的单库即可完成任何增 删 改 查的业务操作 随着业务的发展 xff0c 单个DB中保存的数据量 xff08 用户 订单 计费
  • 1024

    听说今天发帖能有1024勋章 xff1f
  • 神奇!明明是 socket,被我玩成了 http!

    颓废青年 xff0c 快出来挨打 xff01 点击上方 Java极客技术 xff0c 选择 设为星标 后台回复 java xff0c 获取Java知识体系 面试必看资料 资料会持续更新 xff0c 已更新第四次 xff01 文章精品专栏 记

随机推荐

  • python画图程序

    usr bin python coding utf 8 import wx import wx lib buttons as buttons import wx adv as adv import wx lib colourselect a
  • 升级到tensorflow2.0,我整个人都不好了

    版本升级到 tensorflow 2 0 的悲惨经历 没事别升级 Tensorflow 2 0发布已经有一段时间了 xff0c 各种基于新API的教程看上去的确简单易用 xff0c 一个简单的mnist手写识别只需要下面不到20行代码就OK
  • 修改conda环境和缓存默认路径

    默认情况下 xff0c conda 创建的新环境 以及过往安装的模块缓存都存储在用户目录下 xff0c 这一点不会在 conda xff08 user specific xff09 配置文件 HOME condarc 中体现出来 xff0c
  • 融合人体姿态估计和目标检测的学生课堂行为识别

    融合人体姿态估计和目标检测的学生课堂行为识别 参考网 摘要 xff1a 在課堂教学中 xff0c 人工智能技术可以帮助实现学生行为分析自动化 xff0c 让教师能够高效且直观地掌握学生学习行为投入的情况 xff0c 为后续优化教学设计与实施
  • Python实例详解pdfplumber读取PDF写入Excel

    一 Python操作PDF 13大库对比 PDF xff08 Portable Document Format xff09 是一种便携文档格式 xff0c 便于跨操作系统传播文档 PDF文档遵循标准格式 xff0c 因此存在很多可以操作PD
  • 如何使用ChatGPT API训练自定义知识库AI聊天机器人

    原文 xff1a 如何使用ChatGPT API训练自定义知识库AI聊天机器人 闪电博 在我们之前的文章中 xff0c 我们演示了如何用ChatGPT API建立一个AI聊天机器人 xff0c 并指定一个角色来进行个性化处理 但如果你想在自
  • 哈工大团队开源医学智能问诊大模型 | 华佗: 基于中文医学知识的LLaMa指令微调模型

    原文 xff1a CVHub 门头沟学院AI视觉实验室御用公众号 学术 科研 就业 185篇原创内容 公众号 Title HuaTuo Tuning LLaMA Model with Chinese Medical Knowledge PD
  • 开源数字人Fay

    原文 xff1a 别再因AI焦虑 xff0c 这波年轻人已经用 中国版ChatGPT 创业成功了 数字人 AI 创业 新浪新闻 开源 xff1a GitHub TheRamU Fay Fay是一个完整的开源项目 xff0c 包含Fay控制器
  • 推荐 3 个令你惊艳的 GitHub 项目

    原文 xff1a 推荐 3 个令你惊艳的 GitHub 项目 昨日 GitHub Trending 上榜的开源项目 xff0c 基于 AI 技术提高你的生产力 借助 AI 你能搭建自己的数字人 搭建自己的法律助手 文档分析助手 本期推荐开源
  • AI 数字人制作(方案一):输入一张图片和一段文字即可生成数字人

    方案一 xff1a 原文 xff1a AI 数字人制作 xff08 方案一 xff09 哔哩哔哩 bilibili AI 文字和图片生成数字人 输入一张图片和一段文字即可生成数字人 用三个开源项目整合成可以商用的数字人项目 文本生成语音开源
  • 大量数据情况下单线程插入和多线程insert数据库的性能测试

    大量数据情况下单线程插入和多线程insert数据库的性能测试 之前一直没有遇到过大批量数据入库的场景 xff0c 所以一直没有思考过在大量数据的情况下单线程插入和多线程插入的性能情况 今天在看一个项目源代码的时候发现使用了多线程insert
  • 查看tensorflow 安装目录

    使用命令 xff1a pip show f tensorflow 图和张量源码 xff1a C Program Files Anaconda3 Lib site packages tensorflow python framework op
  • FP-growth算法,fpgrowth算法详解

    FP growth算法 xff0c fpgrowth算法详解 使用FP growth算法来高效发现频繁项集 前言 你用过搜索引擎挥发现这样一个功能 xff1a 输入一个单词或者单词的一部分 xff0c 搜索引擎酒会自动补全查询词项 xff0
  • 如何将一个矩阵化为行阶梯形矩阵

    2016 03 29 尾巴 线性代数 有同学反映上一课过于冷冰冰 xff0c 都是一些不带证明的公式 如果线性代数所有公式都要证明的话 xff0c 线性代数的难度会上好几个量级 xff0c 有的公式的证明是特别特别难的 还有一个 xff0c
  • Activity启动模式与任务栈(Task)全面深入记录(上)

    转载请注明出处 xff08 谢谢 xff09 xff1a http blog csdn net javazejian article details 52071885 任务栈简单入门 最近又把两本进阶书看了一遍 xff0c 但总感觉好记性不
  • VSCode自定义代码片段3——url大全

    url大全 url 39 3 如何自定义用户代码片段 xff1a VSCode 61 左下角设置 61 用户代码片段 61 新建全局代码片段文件 61 自定义片段名称 61 编辑用户片段 61 ctrl 43 S 保存 url大全 34 P
  • mac中如何使用vsode愉快地运行C、C++程序

    闲来无事 xff0c 想在mac中写写C C 43 43 程序 xff0c 打开应用商店 xff0c 准备下个xcode玩玩 xff0c 结果小30G的空间占用直接劝退 因为一直使用vscode开发 xff0c 便萌生了使用插件来运行C C
  • CMake入门3之 静态链接库和动态链接库

    目录 目标 xff1a 环境 创建静态和动态链接库 文件准备 构建 安装静态链接库 使用静态链接库和动态库 使用动态库 使用静态库 目标 xff1a 构建静态链接库和动态链接库 xff0c 安装到系统 xff0c 写一个程序使用安装的静态链
  • 行人检测数据集

    MIT数据库 该数据库为较早公开的行人数据库 xff0c 共924张行人图片 xff08 ppm格式 xff0c 宽高为64 128 xff09 xff0c 肩到脚的距离约80象素 该数据库只含正面和背面两个视角 xff0c 无负样本 xf
  • opencv中solvePnPRansac函数求解相机位姿

    PnP xff08 Perspective n Points xff09 xff1a 2D 3D xff0c 求解相机位姿 PnP xff08 Perspective n Points xff09 就是你有n个点的3D位置和它们的投影 xf