预备知识
 
图像坐标系:

 
理想的图像坐标系原点O1和真实的O0有一定的偏差,由此我们建立了等式(1)和(2),可以用矩阵形式(3)表示。
相机坐标系(C)和世界坐标系(W):

通过相机与图像的投影关系,我们得到了等式(4)和等式(5),可以用矩阵形式(6)表示。
我们又知道相机坐标系和世界坐标的关系可以用等式(7)表示:

由等式(3),等式(6)和等式(7)我们可以推导出图像坐标系和世界坐标系的关系:

其中M1称为相机的内参矩阵,包含内参(fx,fy,u0,v0)。M2称为相机的外参矩阵,包含外参(R:旋转矩阵,T:平移矩阵)。
众所周知,相机镜头存在一些畸变,主要是径向畸变(下图dr),也包括切向畸变(下图dt)等。

上图右侧等式中,k1,k2,k3,k4,k5,k6为径向畸变,p1,p2为切向畸变。在OpenCV中我们使用张正友相机标定法通过10幅不同角度的棋盘图像来标定相机获得相机内参和畸变系数。
 
R的第i行表示摄像机坐标系中的第i个坐标轴方向的单位向量在世界坐标系里的坐标;R的第i列表示世界坐标系中的第i个坐标轴方向的单位向量在摄像机坐标系里的坐标;T正好是世界坐标系的原点在摄像机坐标系的坐标,特别的,Tz就代表世界坐标系的原点在摄像机坐标系里的“深度”。
 
函数原型
 
 cv2.solvePnP(objectPoints, imagePoints, cameraMatrix, distCoeffs[, rvec[, tvec[, useExtrinsicGuess[, flags]]]]) → retval, rvec, tvec
 
参数解释
 
  • objectPoints:世界坐标系中的3D点坐标,单位mm
  • imagePoints:图像坐标系中点的坐标,单位像素
  • cameraMatrix:相机内参矩阵
  • distCoeffs:畸变系数
  • rvec:旋转矩阵
  • tvec:平移矩阵
  • useExtrinsicGuess:是否输出平移矩阵和旋转矩阵,默认为false
  • flags:SOLVEPNP _ITERATIVE、SOLVEPNP _P3P、SOLVEPNP _EPNP、SOLVEPNP _DLS、SOLVEPNP _UPNP
 
内参矩阵和畸变系数都是要通过标定得到的,这个不细讲,opencv官方提供了有标定例子。函数输出的是旋转矩阵rvec和tvec。
 
代码例子
 
我们的问题就是,人站在某点拍摄世界坐标系的原点Ow(下标w表示该坐标是在世界坐标系中的),拍摄出的原点正好落在图像中心,现在我通过某种方法(解PNP问题)计算出Ow在相机坐标系下的坐标为(下标c表示该坐标定义在相机坐标系内),求相机或者说是人位于世界坐标系的哪里。
 
 improt cv2 as cv
 import numpy as np
 objPoints = np.array([[],[],[]])
 imgPoints = np.array([])
 cameraMatrix = np.array()
 distCoeffs = np.array()
 retval,rvec,tvec = cv.solvePnP(objPoints,imgPoints,cameraMatrix,distCoeffs)
 
 
应用
 
应用在robomaster比赛里,就是通过测量装甲实际宽高(单位mm),通过摄像机识别到装甲,然后得到装甲在图像中的坐标,进而利用solvePnP得到rvec,这正好是世界坐标系原点相对于摄像机坐标系的坐标(单位mm),那么z就是距离咯,我们标定装甲的中心为世界坐标系原点,那么就直接得到了装甲中心相对于摄像机坐标系的坐标,通过角度计算就拿到偏移角度,再调试得到摄像机坐标系坐标原点到云台坐标系的偏移值,通过简单运算就得到装甲中心相对云台坐标系的坐标,我们就可以攻击它啦。
 
 
 
参考:
OpenCV相机标定和姿态更新:https://www.cnblogs.com/mikewolf2002/p/5746667.html
Opencv249和Opencv3.0以上的 SolvePnp函数详解(附带程序、算例):https://blog.csdn.net/qq_30547073/article/details/78656795
OpenCV官方文档:https://docs.opencv.org/2.4/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html
根据四个特征点估计相机姿态:http://www.cnblogs.com/singlex/p/pose_estimation_1.html
 

cv2.solvepnp 相机的位姿估计的更多相关文章

  1. python+opencv2相机位姿估计

    最近在做基于图像的室内定位方面的研究,于是使用到了百度最新的室内数据库Image-based Localization (IBL) .由于该数据库给出的数据是每幅图像和其对应相机的内外参数和光心投影方 ...

  2. 相机位姿估计1_1:OpenCV:solvePnP二次封装与性能测试

    关键词:OpenCV::solvePnP 文章类型:方法封装.测试 @Author:VShawn(singlex@foxmail.com) @Date:2016-11-27 @Lab: CvLab20 ...

  3. 相机位姿估计0:基本原理之如何解PNP问题

    关键词:相机位姿估计 PNP问题求解 用途:各种位姿估计 文章类型:原理 @Author:VShawn(singlex@foxmail.com) @Date:2016-11-18 @Lab: CvLa ...

  4. 物体的三维识别与6D位姿估计:PPF系列论文介绍(三)

    作者:仲夏夜之星 Date:2020-04-08 来源:物体的三维识别与6D位姿估计:PPF系列论文介绍(三) 文章“A Method for 6D Pose Estimation of Free-F ...

  5. 【转】【计算机视觉】opencv靶标相机姿态解算2 根据四个特征点估计相机姿态 及 实时位姿估计与三维重建相机姿态

    https://blog.csdn.net/kyjl888/article/details/71305149

  6. 机器学习进阶-光流估计 1.cv2.goodFeaturesToTrack(找出光流估计所需要的角点) 2.cv2.calcOpticalFlowPyrLK(获得光流检测后的角点位置) 3.cv2.add(进行像素点的加和)

    1.cv2.goodFeaturesToTrack(old_gray, mask=None, **feature_params)  用于获得光流估计所需要的角点参数说明:old_gray表示输入图片, ...

  7. 阅读高翔的RGBD-SLAM博文笔记

    目录 高翔的RGBD-SLAM笔记 前端VO: 后端优化 高翔的RGBD-SLAM笔记 RGBD相机的特点: 使用RGBD相机中的深度这一维信息,以及相机的针孔成像模型,相机的内参,可以将二维点恢复成 ...

  8. ORB-SLAM2初步(跟踪模块)

    一.跟踪模块简介 在ORB-SLAM或其他SLAM系统中,跟踪的主要任务是根据相机或视频输入的图像帧实时输出相机位姿.在ORB-SLAM中,跟踪模块的主要任务是实时输出相机位姿和筛选关键帧,完成一个没 ...

  9. CCF虚拟现实与可视化技术专委会丨面向增强现实的可视计算技术研究进展概述

    https://mp.weixin.qq.com/s/I-rNwgXHEtwgdpkWzKtVXw 摘要 新一代增强现实技术需要依赖可视计算理论与方法解决大尺度复杂环境下的场景建模.内容生成.感知交互 ...

随机推荐

  1. php查询内存信息

    php查询内存信息,是为了更好的查看内存使用情况,更好的优化代码. 查看当前内存使用情况使用:memory_get_usage()函数. 查看内存使用峰值:memory_get_peak_usage( ...

  2. JavaScript操作服务器控件之Gridview控件

    1.JavaScript脚本如下: <script language="javascript" type="text/javascript">    ...

  3. Linear Algebra - Determinant(基础)

    1. 行列式的定义 一阶行列式: \[ \begin{vmatrix} a_1 \end{vmatrix} = a_1 \] 二阶行列式: \[ \begin{vmatrix} a_{11} & ...

  4. [poj百练]2754:八皇后 回溯

    描述 会下国际象棋的人都很清楚:皇后可以在横.竖.斜线上不限步数地吃掉其他棋子.如何将8个皇后放在棋盘上(有8 * 8个方格),使它们谁也不能被吃掉!这就是著名的八皇后问题. 对于某个满足要求的8皇后 ...

  5. java接口中成员变量和方法的默认修饰符(转)

    Java的interface中,成员变量的默认修饰符为:public static final 所以我们在interface中定义成员变量的时候,可以 1:public static final St ...

  6. php UTF8 转字节数组,后使用 MD5 计算摘要

    Hex.encodeHexString(md5.digest);按 UTF8 转字节数组,后使用 MD5 计算摘要,得到 16 字节数组,使用 Hex 转为长度为 32 的字符串,保持小写 bin2h ...

  7. 小a和uim之大逃离(luogu P1373 dp)

    小a和uim之大逃离(luogu P1373 dp) 给你一个n*m的矩阵,其中元素的值在1~k内.限制只能往下和往右走,问从任意点出发,到任意点结束,且经过了偶数个元素的合法路径有多少个.在此题中, ...

  8. JAVA接口详细讲解

    接口 接口的概念  接口代表的是一个功能的集合,定义规范,所有的方法都是抽像方法,这是一种思想是一种规则,将这个种规则称为接口. 接口的定义 使用关键字 interface 叫做接口 修饰符 inte ...

  9. 在双系统(Win7和Ubuntu Kylin)中卸载Ubuntu

    由于以前学习Linux相关的知识,所以在win7的基础上装了ubuntu系统,最近在使用中老是出现一些问题,想将其卸载,于是在网上找了些相关方法. 我每次开机时,都会出现GRUB界面(我需要选择要进入 ...

  10. require--按需加载js与模块化

    1.html中:  “<script type="text/javascript" src="js/require.js" data-main=" ...